可能重复:
C++ difference of keywords ‘typename’ and ‘class’ in templates
在C ++中定义函数模板或类模板时,可以写下:
template <class T> ...
或者可以写下这个:
template <typename T> ...
是否有充分的理由选择其中一个?
我接受了最受欢迎(也很有趣)的答案,但真正的答案似乎是“不,没有理由更喜欢一个而不是另一个。”
typename
。class
。但请注意,对于模板模板参数,需要使用class
代替typename
。请参阅下面的user1428839's answer。 (但这个特殊情况不是偏好问题,而是语言的要求。)(这也会随着c++17
而改变)
答案 0 :(得分:383)
Stan Lippman谈到了here。我觉得这很有意思。
摘要:Stroustrup最初使用class
来指定模板中的类型,以避免引入新关键字。委员会中的一些人担心这种关键字的超载导致了混乱。后来,委员会引入了一个新的关键字typename
来解决语法歧义,并决定让它也用于指定模板类型以减少混淆,但为了向后兼容,class
保持其重载意义。 / p>
答案 1 :(得分:297)
根据Scott Myers的说法,Effective C ++(第3版)第42项(当然,这必须是最终答案) - 差异是“没有”。
建议是使用“class”如果预期T将永远是一个类,如果可能需要其他类型(int,char *,则为“typename”)。考虑一下使用提示。
答案 2 :(得分:143)
作为上述所有帖子的补充,在处理模板模板时,强制使用class
关键字 <(包括C ++ 14) i>参数,例如:
template <template <typename, typename> class Container, typename Type>
class MyContainer: public Container<Type, std::allocator<Type>>
{ /*...*/ };
在此示例中,typename Container
会产生编译器错误,如下所示:
error: expected 'class' before 'Container'
答案 3 :(得分:47)
我更喜欢使用typename,因为我不喜欢重载的关键字(jeez - static
对于各种不同的上下文有多少不同的含义?)。
答案 4 :(得分:15)
class
到typename
。 typename
对于模板模板参数是非法的,因此为了保持一致,您应该使用class
:
template<template<class> typename MyTemplate, class Bar> class Foo { }; // :(
template<template<class> class MyTemplate, class Bar> class Foo { }; // :)
答案 5 :(得分:9)
在回复Mike B时,我更喜欢使用'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
是一种类型。另一方面,类没有这样的重载意义。
那......或者我只是在懒惰。我输入'class'比'typename'更频繁,因此更容易输入。或者它可能是我写了太多OO代码的标志。
答案 6 :(得分:9)
纯粹的历史。 Quote from Stan Lippman:
这两个关键字的原因是历史性的。在原始模板规范中,Stroustrup重用现有的class关键字来指定类型参数,而不是引入可能会破坏现有程序的新关键字。这不是一个新的关键词没有被考虑 - 只是因为它可能被破坏而被认为是不必要的。直到ISO-C ++标准,这是声明类型参数的唯一方法。
但是应该使用 typename 而不是 class ! 有关详细信息,请参阅链接,但请考虑以下代码:
template <class T>
class Demonstration {
public:
void method() {
T::A *aObj; // oops ...
};
答案 7 :(得分:7)
根本不重要,但是类使它看起来像T只能是一个类,而它当然可以是任何类型。所以typename更准确。另一方面,大多数人使用类,因此通常更容易阅读。
答案 8 :(得分:1)
据我所知,你使用哪一个并不重要。它们在编译器的眼中是等价的。使用您喜欢的任何一种。我通常会上课。
答案 9 :(得分:-3)
扩展DarenW的评论。
一旦不接受typename和class非常不同,它们的使用可能仍然有效。仅当class真的是类时才使用class,而当它是基本类型时使用typename,例如 char 。
这些类型确实也被接受,而不是 typename
模板&LT; char myc ='/'&gt;
在这种情况下甚至优于typename或class。
想想其他人的“暗示”或可理解性。并且实际上考虑到第三方软件/脚本可能会尝试使用代码/信息来猜测模板发生了什么(考虑swig)。