Использовать '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).