0Pricing
C++ Academy · درس

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 يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. enum class ذات نطاق
  2. الاتحادات ومخاطرها
  3. std::variant
  4. std::visit
← العودة إلى C++ Academy