تخطَّ إلى المحتوى

std::expected

std::expected: نتيجة صحيحة أو خطأ موصوف std::expected

std::expected<T, E> من <expected> يحمل إمّا قيمة صحيحة من النوع T أو خطأ موصوف من النوع E — بديل صريح للاستثناءات بحالات الخطأ المتوقّعة.

std::optional يمثّل "لا توجد قيمة" لكنه لا يخبرك لماذا. std::expected<T, E> من C++23 يوسّع الفكرة: يحمل إمّا نتيجة صحيحة (T) أو خطأً موصوفًا (E) يوضّح سبب الفشل، دون تكلفة رمي والتقاط استثناء. تُنشأ حالة الخطأ عبر std::unexpected(value)، وتُفحص عبر has_value()/operator bool، وتُقرأ القيمة عبر value() أو * أو الخطأ عبر error().

الصياغة

std::expected<T, E> func(...) {
    if (/* فشل */) return std::unexpected(errorValue);
    return value; // نجاح
}

📄 مثال

#include <expected>
#include <string>

std::expected<int, std::string> parsePositive(const std::string& text) {
    try {
        int n = std::stoi(text);
        if (n <= 0) return std::unexpected("الرقم يجب أن يكون موجبًا");
        return n;
    } catch (...) {
        return std::unexpected("نص غير قابل للتحويل");
    }
}

أهم النقاط

العنصرالوظيفة
has_value() / operator boolهل النتيجة صحيحة (لا خطأ)؟
value() / operator*الوصول للقيمة الصحيحة — value() يرمي استثناء لو كانت خطأ
error()الوصول لوصف الخطأ — صالح فقط لو has_value() كانت false

💡 نصائح عملية

  • استخدمه لأخطاء متوقّعة يتعامل معها المستدعي عادة (إدخال خاطئ، ملف غير موجود)، واترك الاستثناءات للحالات الاستثنائية فعلًا
  • متاح في GCC 12+ وMSVC 19.33+ — تحقّق من إصدار مترجمك قبل الاعتماد عليه بمشروع فعلي

⚠️ أخطاء شائعة

  • استدعاء value() على expected يحمل خطأ دون فحص has_value() أولًا — يرمي استثناء تمامًا مثل optional الفارغ
  • استخدام expected بمكان تحتاج فيه فعليًا استثناء ينتشر عبر عدّة طبقات استدعاء دون معالجة صريحة بكل طبقة

خصائص ذات صلة

🎓 تريد فهم الصورة الكاملة خطوة بخطوة؟ ابدأ من مسار CPP الكامل بالعربي.