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 الكامل بالعربي.