decltype
استنتاج نوع تعبير موجود decltype
decltype يستخرج نوع تعبير موجود دون تقييمه فعليًا — مكمّل لـ auto، ومفيد خصوصًا بالقوالب لما يعتمد نوع الإرجاع على أنواع المعاملات.
بينما auto يستنتج النوع من قيمة ابتدائية، decltype(expr) يعطيك نوع تعبير قائم بالفعل دون تنفيذه. الفرق المهم عن auto: decltype يحافظ بدقة أكبر على المرجعية وconst — لو التعبير lvalue، تحصل على مرجع للنوع؛ لو rvalue، تحصل على النوع مباشرة. الاستخدام الأشيع بمكتبات القوالب: تحديد نوع إرجاع دالة generic يعتمد على أنواع معاملاتها (trailing return type).
الصياغة
decltype(expression) name;
auto func(...) -> decltype(expression) { ... } // C++11 trailing return type📄 مثال
int x = 5;
decltype(x) y = 10; // int — نفس نوع x
template<typename T1, typename T2>
auto sum(T1 a, T2 b) -> decltype(a + b) {
return a + b; // نوع الإرجاع يُستنتج من نوع a + b فعليًا
}
sum(3, 4.5); // النوع المُستنتج: doubleأهم النقاط
| العنصر | الوظيفة |
|---|---|
| decltype(var) | نوع المتغيّر كما عُرِّف بالضبط |
| decltype(expr) | لو expr rvalue، النوع مباشرة؛ لو lvalue، مرجع للنوع |
| decltype(auto) | C++14 — نسخة أدق تحافظ تلقائيًا على المرجعية وconst بدل كتابة decltype يدويًا |
💡 نصائح عملية
- استخدمه مع trailing return type لما نوع إرجاع دالة قالب يعتمد على أنواع المعاملات ولا يمكن كتابته صراحة
- لكتابة كود عادي غير قوالب، auto وحدها كافية غالبًا — decltype أداة متخصّصة لمطوّري المكتبات
⚠️ أخطاء شائعة
- الخلط بينه وبين auto — auto يحتاج قيمة ابتدائية ويستنتج منها، decltype يأخذ تعبيرًا موجودًا فقط
- وضع أقواس إضافية حول اسم متغيّر decltype((var)) ظنًا أنها بلا تأثير — تغيّر النتيجة فعليًا لمرجع بدل النوع المباشر
خصائص ذات صلة
🎓 تريد فهم الصورة الكاملة خطوة بخطوة؟ ابدأ من مسار CPP الكامل بالعربي.