std::variant
اتحاد آمن من ناحية النوع
std::variant درس مجاني في C++ Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C++ Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C++ Academy 4 دروس في المجموع.
اتحاد آمن من ناحية الأنواع
يحتوي std::variant على قيمة واحدة بالضبط من قائمة ثابتة من الأنواع، ويتذكّر نوعها. أدرجوا <variant> لاستخدامه.
#include <iostream>
#include <variant>
int main() {
std::variant<int, double> v = 10;
std::cout << std::get<int>(v) << "\n";
}إسناد أنواع مختلفة
يمكنكم إعادة إسناد variant إلى أي نوع من أنواعه البديلة. وهو يحدّث البديل النشط تلقائيًا.
#include <iostream>
#include <variant>
int main() {
std::variant<int, double> v = 5;
v = 3.14; // now holds a double
std::cout << std::get<double>(v) << "\n";
}التحقق من النوع النشط
تُخبركم std::holds_alternative<T>(v) بما إذا كان variant يحتوي حاليًا على النوع T.
#include <iostream>
#include <variant>
int main() {
std::variant<int, double> v = 2.0;
std::cout << std::holds_alternative<double>(v) << "\n";
std::cout << std::holds_alternative<int>(v) << "\n";
}الدالة index()
تعيد v.index() موضع النوع النشط، بدءًا من الصفر، في قائمة الأنواع.
#include <iostream>
#include <variant>
int main() {
std::variant<int, double, char> v = (char)65;
std::cout << v.index() << "\n"; // 2
}وصول آمن باستخدام std::get
تعيد std::get<T> القيمة إذا كان T نشطًا، وإلا فإنها ترمي std::bad_variant_access. لا توجد قيم عشوائية صامتة.
#include <iostream>
#include <variant>
int main() {
std::variant<int, double> v = 7;
try {
std::cout << std::get<double>(v) << "\n";
} catch (const std::bad_variant_access& e) {
std::cout << "wrong type!\n";
}
}get_if دون رمي استثناء
تعيد std::get_if<T>(&v) مؤشرًا إلى القيمة، أو nullptr إذا لم يكن T نشطًا. وهي مناسبة جدًا لعمليات التحقق دون تفرّع.
#include <iostream>
#include <variant>
int main() {
std::variant<int, double> v = 9;
if (auto p = std::get_if<int>(&v))
std::cout << "int " << *p << "\n";
}الإنشاء الافتراضي
يحتوي variant المُنشأ افتراضيًا على نسخة مهيّأة بالقيمة من نوعه الأول. رتّبوا الأنواع بحيث يكون النوع الأول افتراضيًا منطقيًا.
#include <iostream>
#include <variant>
int main() {
std::variant<int, double> v; // holds int 0
std::cout << std::get<int>(v) << "\n";
}تخزين السلاسل النصية
بخلاف الاتحادات الخام، يستطيع variant احتواء أنواع غير بسيطة مثل std::string بأمان؛ إذ تُدار دورة الحياة نيابةً عنكم.
#include <iostream>
#include <string>
#include <variant>
int main() {
std::variant<int, std::string> v = std::string("hello");
std::cout << std::get<std::string>(v) << "\n";
}استخدام variant كنوع إرجاع
يمكن للدالة إرجاع أحد عدة أنواع من خلال إرجاع variant. ثم يفحصه المستدعون لمعرفة النوع الذي أُعيد.
#include <iostream>
#include <string>
#include <variant>
std::variant<int, std::string> parse(bool ok) {
if (ok) return 42;
return std::string("error");
}
int main() {
auto r = parse(false);
if (auto s = std::get_if<std::string>(&r)) std::cout << *s << "\n";
}استخدام emplace للتغيير في مكانه
تنشئ v.emplace<T>(args...) قيمة جديدة من النوع T مباشرةً داخل variant، وتبدّل البديل النشط.
#include <iostream>
#include <string>
#include <variant>
int main() {
std::variant<int, std::string> v = 1;
v.emplace<std::string>("switched");
std::cout << std::get<std::string>(v) << "\n";
}لماذا نفضّل Variant؟
يمنحكم std::variant كفاءة الاتحادات في استخدام الذاكرة مع أمان كامل للأنواع: فهو يتتبّع النوع النشط، ويدير دورات الحياة، ويرفض الوصول إلى النوع الخطأ. يوضّح الدرس التالي أنظف طريقة لمعالجته.
تحقق سريع
تحقّقوا من فهمكم لـ std::variant.
مراجعة
تعلّمتم std::variant:
- يحتوي على أحد عدة أنواع ويتتبّع النوع الموجود.
- تفحص
holds_alternative/index()النوع النشط. - ترمي
std::getاستثناءً عند عدم التطابق؛ بينما تعيدget_ifمؤشرًا أو قيمة null. - يخزّن بأمان الأنواع غير البسيطة مثل
std::string.
الأسئلة الشائعة
هل درس «std::variant» مجاني؟
نعم — نص درس «std::variant» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C++ Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C++ Academy 4 دروس في المجموع.
ماذا ستتعلم في «std::variant»؟
اتحاد آمن من ناحية النوع تتمرن على C++ Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ C++ Academy؟
لا تُشترط خبرة سابقة. C++ Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.
كم من الوقت يستغرق درس «std::variant»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس C++ Academy هذا؟
نعم. كل درس في C++ Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- enum class ذات نطاق
- الاتحادات ومخاطرها
- std::variant
- std::visit