c++ - لماذا لا تسمح معلمة قالب القالب "typename" بعد قائمة المعلمات




templates c++11 (2)

أنا أبحث عن عقلاني وراء هذا القيد [...]

قبل عرض C ++ 11 ، كانت القوالب الوحيدة التي يمكنك تمريرها إلى معلمة قالب قالب هي قوالب الفئات. هذا هو السبب في فرض استخدام class الكلمة الرئيسية. بالإضافة إلى ذلك ، فإن الكلمة الرئيسية typename تشير إلى أن معلمة القالب هي استبدال نوع تعسفي وليست قالبًا ، لذلك فإن استخدام typename في هذا السياق يؤدي فقط إلى طمس الخط الفاصل بين أسماء الأنواع والقوالب ( class ). هذا مفهوم.

في الوقت الحاضر ، يمكن أن تكون مثل هذه الحجج أسماء قوالب الصفوف أو قوالب الاسم المستعار ، وبما أن هذه ليست مرتبطة عن بعد ، فإن إنفاذ class الكلمة الرئيسية أصبح أكثر أو أقل عفا عليه الزمن. ويقترح الاقتراح N4051 تغيير ذلك باستخدام C ++ 1Z.

قالب قالب الاسم؟

عند استخدام بناء قالب قالب كما في template <template <typename> class T> ، فإنه يلزم استخدام class الكلمة الرئيسية ، حيث إن استخدام اسم typename يعطي خطأ على أساس:

الخطأ: تتطلب معلمة قالب القالب "class" بعد قائمة المعلمات

في كل مكان آخر ، تكون typename المفتاحية typename و class قابلة للتبادل في الحالة الأساسية للتصريح بمعلمة قالب.

يمكنك أن تجادل بأن المتطلب عند استخدام قالب القالب هو تلميح يتوقع منك تمرير نوع الفئة ، ولكن هذا ليس هو الحال دائمًا (خاصةً بعد أن يكون C ++ 11 قد قدم أسماء مستعارة من نوع templated).

template <template <typename> class T> // 'class' keyword required.
struct Foo {
    using type = T<int>;
};

template <typename T>
using type = T (*)();

using func_ptr_t = Foo<type>::type;

ما السبب خلف هذا؟

  • هل هناك أي سبب محدد لسبب عدم typename في إعلانات قالب القالب؟
  • هل يقول معيار C ++ أي شيء عن هذا؟

إجابة قصيرة : لأن المعيار يقول ذلك .

إجابة أطول : قبل القياسات القياسية ، تتطلب قوالب C ++ الكلمة الأساسية class لجميع معلمات القالب. ومع ذلك ، للتأكيد على حقيقة أن القوالب يمكن أن تكون أيضًا من نوع غير فئة (أي بنيت) ، تم إدخال اسم بديل للكلمة الرئيسية. ومع ذلك ، في C ++ 98 ، يمكن أن تكون معلمات قالب القالب فقط من نوع الفئة ، وهذا هو السبب في أن الكلمة المفتاحية typename لم تتم إضافتها في هذا السياق.

أدخِل C ++ 11 وأزراره المستعارة لقالب الميزات الجديد ، والتي قدمت الآن أيضًا قوالبًا غير تابعة للفئة ، وبالتالي معلمات قالب القوالب غير التابعة للفئة:

template<typename T> struct A {};
template<typename T> using B = int;

template<template<typename> class X> struct C;
C<A> ca; // ok
C<B> cb; // ok, not a class template
template<template<typename> typename X> struct D; // error, cannot use typename here

تم أخذ المثال المذكور أعلاه من مقترح C ++ 1z الحالي N4051 بعنوان " سماح typename في معلمة قالب قالب" ، ويقترح السماح بذلك بدقة.

Clang 3.5 SVN يدعم هذا الآن مع علامة -std=c++1z .







typename