c++ - اختلاف كلمة "nameen" للكلمات الرئيسية و "class" في القوالب؟




templates keyword (4)

  1. لا فرق
  2. معلمة نوع القالب إن Container عبارة عن قالب ذو معلمتين نوع.

بالنسبة للقوالب ، رأيت كلا التعريفين:

template < typename T >
template < class T >

ماهو الفرق؟

وماذا تعني هذه الكلمات بالضبط في المثال التالي (مأخوذة من مقالة Wikipedia الألمانية عن القوالب)؟

template < template < typename, typename > class Container, typename Type >
class Example
{
     Container< Type, std::allocator < Type > > baz;
};

بالنسبة لتسمية معلمات القالب ، يكون كل من typename و class معادلاً. §14.1.2:

لا يوجد فرق دلالي بين الفئة واسم الملف في معلمة قالب.

ومع ذلك ، فإن typename ممكن في سياق آخر عند استخدام القوالب - للإشارة إلى المحول البرمجي أنك تشير إلى نوع تابع. §14.6.2:

يُفترض أن الاسم المستخدم في تعريف القالب أو تعريفه والذي يعتمد على معلمة القالب لا يهدف إلى تسمية نوع ما إلا إذا عثر بحث الاسم المطابق عن اسم نوع أو أن الاسم مؤهل بواسطة الكلمة المفتاحية typename.

مثال:

typename some_template<T>::some_type

بدون typename لا يستطيع المترجم أن يخبر بشكل عام ما إذا كنت تشير إلى نوع أم لا.


هذه القطعة من المقتطف هي من كتاب التمهيدي c + +. على الرغم من أنني متأكد من أن هذا خطأ.

يجب أن تكون كل معلمة نوع مسبوقة بفئة الكلمة الرئيسية أو اسم الملف الرئيسي:

// error: must precede U with either typename or class
template <typename T, U> T calc(const T&, const U&);

هذه الكلمات الرئيسية لها نفس المعنى ويمكن استخدامها بشكل تبادلي داخل قائمة معلمات القالب. يمكن أن تستخدم قائمة معلمات القالب كلتا الكلمتين الرئيسيتين:

// ok: no distinction between typename and class in a template parameter list
template <typename T, class U> calc (const T&, const U&);

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


typename و class للتبادل في الحالة الأساسية لتحديد قالب:

template<class T>
class Foo
{
};

و

template<typename T>
class Foo
{
};

ما يعادل.

بعد قولي هذا ، هناك حالات محددة حيث يوجد اختلاف بين typename و class .

النوع الأول هو في حالة الأنواع التابعة. يتم استخدام typename عند الإشارة إلى نوع متداخل يعتمد على معلمة قالب أخرى ، مثل typedef في هذا المثال:

template<typename param_t>
class Foo
{
    typedef typename param_t::baz sub_t;
};

الثاني الذي تظهره فعليًا في سؤالك ، رغم أنك قد لا تدرك ذلك:

template < template < typename, typename > class Container, typename Type >

عند تحديد قالب قالب ، يجب استخدام الكلمة الأساسية class على النحو الوارد أعلاه - لا يمكن typename باسم typename في هذه الحالة (ملاحظة: حيث أن C ++ 17 يُسمح بكلتا الكلمتين في هذه الحالة) .

يجب عليك أيضًا استخدام class عند إنشاء قالب بشكل صريح:

template class Foo<int>;

أنا متأكد من أن هناك حالات أخرى فاتني ، ولكن خلاصة القول هي: هاتين الكلمتين الرئيسيتين غير متكافئتين ، وهذه بعض الحالات الشائعة التي تحتاج فيها إلى استخدام واحدة أو أخرى.





keyword