c++ استخدم "class" أو "typename" لمعلمات النماذج؟




templates (8)

ممكن تكرار:
اختلاف C ++ لكلمة "typename" للكلمات الرئيسية و "class" في القوالب

عند تعريف قالب دالة أو قالب فئة في C ++ ، يمكن كتابة هذا:

template <class T> ...

أو واحد يمكن أن يكتب هذا:

template <typename T> ...

هل هناك سبب وجيه لتفضيل أحدهما على الآخر؟

قبلت الإجابة الأكثر شعبية (والمثيرة للاهتمام) ، ولكن يبدو أن الإجابة الحقيقية هي "لا ، ليس هناك سبب وجيه لتفضيل أحدهما على الآخر".

  • وهي مكافئة (باستثناء ما هو مذكور أدناه).
  • بعض الناس لديهم أسباب لاستخدام اسم typename دائمًا.
  • لدى بعض الأشخاص أسباب لاستخدام class دائمًا.
  • بعض الناس لديهم أسباب لاستخدام كليهما.
  • بعض الناس لا يهتمون بأي واحد يستخدمونه.

مع ذلك ، لاحظ أنه في حالة معلمات قالب القالب ، يلزم استخدام class بدلاً من اسم typename . راجع إجابة user1428839 أدناه. (لكن هذه الحالة بالذات ليست مسألة تفضيل ، بل هي مطلب للغة.) (سيتغير هذا أيضًا مع c++17 )


بقدر ما أعرف ، لا يهم أي واحد تستخدمه. انهم ما يعادل في عيون المترجم. استخدم أيهما تفضل. أنا عادة استخدام الفصل.


كإضافة إلى جميع المشاركات المذكورة أعلاه ، فإن استخدام الكلمة الأساسية class يتم فرضه ( تحرير: ما يصل إلى 14 ++ C ++ ) عند التعامل مع معلمات قالب القالب ، على سبيل المثال:

template <template <typename, typename> class Container, typename Type>
class MyContainer: public Container<Type, std::allocator<Type>>
{ /*...*/ };

في هذا المثال ، قد يكون typename Container قد typename Container خطأ في المحول البرمجي ، مثل هذا:

error: expected 'class' before 'Container'

راجع http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4051.html لقبول اسم الملف في قالب القالب في C ++ 14.


هناك اختلاف ، ويجب أن تفضل class إلى اسم typename .

لكن لماذا؟

typename غير قانوني typename قالب القالب ، لذلك لتكون متسقة ، يجب عليك استخدام class :

template<template<class> typename MyTemplate, class Bar> class Foo { };    //  :(
template<template<class>    class MyTemplate, class Bar> class Foo { };    //  :)

وفقًا لـ Scott Myers، Effective C ++ (3rd ed.) البند 42 (والذي يجب أن يكون ، بالطبع ، هو الحل النهائي) - الفرق هو "لا شيء".

النصيحة هي استخدام "الفئة" إذا كان من المتوقع أن تكون T دومًا فئة ، مع "typename" إذا كان من المتوقع وجود أنواع أخرى (int، char * whatever). نعتبرها تلميح الاستخدام.


تحدث ستان ليبمان عن هذا here . اعتقد انها كانت مثيرة للاهتمام.

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


مجرد تاريخ خالص. اقتبس من ستان ليبمان :

سبب الكلمتين الرئيسيتين هو تاريخي. في مواصفات القالب الأصلي ، قام Stroustrup بإعادة استخدام الكلمة الأساسية الحالية للفئة لتحديد معلمة نوع بدلاً من تقديم كلمة رئيسية جديدة قد تؤدي بالطبع إلى كسر البرامج الموجودة. لم يكن ذلك هو أن كلمة رئيسية جديدة لم تؤخذ بعين الاعتبار - فقط أنه لم يكن ضروريًا نظرًا لتعطلها المحتمل. وحتى معيار ISO-C ++ ، كانت هذه هي الطريقة الوحيدة لإعلان معلمة نوع.

ولكن يجب على المرء استخدام اسم نوع بدلا من الطبقة ! شاهد الرابط لمزيد من المعلومات ، ولكن فكر في الشفرة التالية:

template <class T>
class Demonstration { 
public:
void method() {
   T::A *aObj; // oops ...
};

أفضّل استخدام اسم ملف لأنني لست من محبي الكلمات الرئيسية الزائدة (jeez - كم عدد المعاني المختلفة التي تحتوي على معاني مختلفة لمختلف السياقات؟).


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







templates