c++ - لماذا لا يكون 'typename` مطلوبًا لفئة أساسية من النوع المتداخل؟




templates inheritance (2)

لقد فوجئت جدًا برؤية أنه ليس من الضروري إضافة typename عندما يظهر نوع تابع كفئة أساسية:

struct B {};

struct wr
{ typedef B type; };

template<class T>
struct A : T::type
{};

int main()
{
    A<wr> a;
    (void)a;
}

لماذا لا يلزم كتابة الاسم أمام T::type ؟


لماذا لا يلزم كتابة الاسم أمام T::type ؟

لأنه لا يمكنك أن ترث من قيمة. يمكنك استخدام typename لإعلام المترجم بأن المعرف المتداخل المحدد هو نوع ، ولكن بالنسبة للميراث ، يجب أن يكون هذا هو الحال على أي حال حتى تتمكن من typename - لهذا السبب توفر اللغة استثناءً من typename - قاعدة typename الأساس. من cppreference (التركيز الألغام):

disambiguator typename للأسماء التابعة

في إعلان أو تعريف لأحد القوالب ، بما في ذلك قالب الاسم المستعار ، لا يعتبر الاسم الذي ليس عضوًا في إنشاء مثيل الحالي ويعتمد على معلمة قالب نوعًا إلا إذا تم استخدام اسم الكلمة الرئيسية أو ما لم يكن بالفعل تم تأسيسه كاسم نوع ، على سبيل المثال مع إعلان typedef أو عن طريق استخدامه لتسمية فئة أساسية .

لاحظ أننا سوف نحصل على المزيد من الأماكن التي يمكن فيها حذف P0634 ، انظر P0634 .


إنها حالة خاصة ، كما لاحظ آخرون. لاقتباس المعيار في هذا:

[temp.res]

5 يُفترض ضمنيًا اسمًا مؤهلًا يستخدم كاسم في فئة أو فئة أحرف مكتوبة أو محدد نوع مُفصَّل لتسمية نوع ما ، دون استخدام الكلمة الأساسية للتسمية. في محدد الاسم المتداخل الذي يحتوي فورًا على محدد الاسم المتداخل الذي يعتمد على معلمة القالب ، يُفترض في المعرف الضمني أو معرف القالب البسيط تسمية نوع ، دون استخدام الكلمة الأساسية للتسمية. [ملاحظة: لا يُسمح باستخدام الكلمة الأساسية لهذه الكلمة الأساسية بناء جملة هذه البنيات. - مذكرة نهاية]

ويأتي C ++ 20 ، سيكون هناك المزيد من الاستثناءات للحاجة إلى typename .





inheritance