Использовать 'class' или 'typename' для параметров шаблона? [дубликат]

Возможные Дубликаты:
C++ разница ключевых слов "typename" и "class" в шаблонах

при определении шаблона функции или шаблона класса В C++ можно написать следующее:

template <class T> ...

или можно написать так:

template <typename T> ...

есть ли веская причина предпочесть одно другому?


Я принял самый популярный (и интересный) ответ, но реальный ответ кажется, "нет, нет веских причин предпочесть одно другому."

  • они эквивалентны (за исключением случаев, указанных ниже).
  • у некоторых людей есть причины всегда использовать typename.
  • у некоторых людей есть причины всегда использовать class.
  • у некоторых людей есть причины, чтобы использовать оба.
  • некоторым людям все равно, какой из них они используют.

обратите внимание, однако, в случае шаблон параметры, использование class вместо это. См.user1428839 это ниже. (Но этот конкретный случай не является вопросом предпочтения, это требование языка.) (Также это изменится с c++17)

10 ответов


Стэн Липпман говорил об этом здесь. Мне это показалось интересным.

резюме: Stroustrup первоначально используется class чтобы указать типы в шаблонах, чтобы избежать введения нового ключевого слова. Некоторые в комитете обеспокоены тем, что такая перегрузка ключевого слова приводит к путанице. Позже, комитет ввел новое ключевое слово typename чтобы разрешить синтаксическую двусмысленность, и решил, что он также будет использоваться для указания типов шаблонов, чтобы уменьшить путаницу, но для обратной совместимости, class сохранил свое перегруженное значение.


согласно Скотту Майерсу, эффективный C++ (3-е изд.) пункт 42 (который должен, конечно, быть окончательным ответом) - разница "ничего".

совет-использовать "класс", если ожидается, что T всегда будет классом, с" typename", если можно ожидать других типов (int, char* whatever). Считайте это подсказкой об использовании.


в качестве дополнения ко всем вышеперечисленным сообщениям, использование class ключевое слово is принудительный (до и включая C++14) при работе с шаблон параметры, например:

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

в этом примере typename Container создал бы ошибку компилятора, что-то вроде этого:

error: expected 'class' before 'Container'

Я предпочитаю использовать typename, потому что я не поклонник перегруженных ключевых слов (Боже - сколько разных значений делает static для разных контекстов?).


здесь is разница, и вы должны предпочесть class to typename.

но почему?

typename является незаконным для аргументов шаблона шаблона, поэтому, чтобы быть последовательным, вы должны использовать class:

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

В ответ Майк Б, Я предпочитаю использовать "class", поскольку в шаблоне "typename" имеет перегруженное значение, но "class" - нет. Возьмите этот проверенный пример целочисленного типа:

template <class IntegerType>
class smart_integer {
public: 
    typedef integer_traits<Integer> traits;
    IntegerType operator+=(IntegerType value){
        typedef typename traits::larger_integer_t larger_t;
        larger_t interm = larger_t(myValue) + larger_t(value); 
        if(interm > traits::max() || interm < traits::min())
            throw overflow();
        myValue = IntegerType(interm);
    }
}

larger_integer_t является зависимым именем, поэтому ему требуется "typename", чтобы предшествовать ему, чтобы парсер мог распознать это larger_integer_t тип. класс, С другой стороны, не имеет такого перегруженного значения.

что... или я просто ленив в душе. Класс Я тип ' далеко чаще ,чем "typename", и, таким образом, найти его гораздо проще ввести. Или это может быть признаком того, что я пишу слишком много ОО код.


просто чистая история. цитата из Стэна Липпмана:

причина двух ключевых слов является исторической. В исходной спецификации шаблона Stroustrup повторно использовал ключевое слово существующего класса, чтобы указать параметр типа, а не вводить новое ключевое слово, которое, конечно, может нарушить существующие программы. Дело не в том, что новое ключевое слово не рассматривалось-просто оно не считалось необходимым, учитывая его потенциальное нарушение. И до стандарта ISO-C++ , это был единственный способ объявить параметр типа.

но нужно использовать typename, а не класс! См. ссылку для получения дополнительной информации, но подумайте о следующем коде:

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

Это не имеет значения, но класс делает его похожим на T может быть только классом, в то время как он, конечно, может быть любым типом. Таким образом, typename более точен. С другой стороны, большинство людей используют класс, так что, вероятно, легче читать в целом.


насколько я знаю, не имеет значения, какой из них вы используете. Они эквивалентны в глазах компилятора. Используйте любой из них. Я обычно использую класс.


продление комментарий DarenW по.

Как только typename и class не принимаются, чтобы быть очень разными, это может быть все еще действительным, чтобы быть строгим в их использовании. Используйте class только если это действительно класс, и typename когда его базовый тип, такой как char.

эти типы действительно также принимаются вместо typename

шаблонchar myc = '/' >

Что будет в этот случай даже превосходит typename или class.

подумайте о" hintfullness " или понятности для других людей. И на самом деле подумайте, что стороннее программное обеспечение/скрипты могут попытаться использовать код/информацию, чтобы угадать, что происходит с шаблоном (рассмотрим swig).