提问人: 提问时间:10/18/2008 最后编辑:18 revs, 8 users 84%Kristopher Johnson 更新时间:9/23/2023 访问量:308479
使用“class”或“typename”作为模板参数?[复制]
Use 'class' or 'typename' for template parameters? [duplicate]
问:
在 C++ 中定义函数模板或类模板时,可以这样写:
template <class T> ...
或者可以这样写:
template <typename T> ...
有没有充分的理由偏爱其中之一?
我接受了最流行(也是最有趣)的答案,但真正的答案似乎是“不,没有充分的理由偏爱一个而不是另一个。
- 它们是等效的(除非下面另有说明)。
- 有些人有理由总是使用 .
typename
- 有些人有理由总是使用 .
class
- 有些人有理由同时使用两者。
- 有些人不在乎他们使用哪一个。
但请注意,在 C++17 之前,对于模板模板参数,需要使用 instead of 代替。请参阅下面的 user1428839 的答案。(但这种特殊情况不是偏好问题,而是语言的要求。class
typename
答:
据我所知,你使用哪一个并不重要。在编译器眼中,它们是等价的。使用您喜欢的任何一个。我通常使用类。
斯坦·李普曼(Stan Lippman)在这里谈到了这一点。我觉得这很有趣。
摘要:Stroustrup 最初用于在模板中指定类型,以避免引入新关键字。委员会中的一些人担心,这种关键词的超载会导致混乱。后来,委员会引入了一个新的关键字来解决句法歧义,并决定让它也用于指定模板类型以减少混淆,但为了向后兼容,保留了其重载的含义。class
typename
class
评论
T::A *obj;
export
T::A
T::A
T::A *obj
f()
f
根据斯科特·迈尔斯(Scott Myers)的说法,有效的C++(第3版)第42项(当然,这必须是最终答案) - 区别是“没有”。
建议使用“class”,如果预期 T 将始终是一个类,则使用“typename”,如果可能期望其他类型(int、char* 等)。将其视为使用提示。
评论
我更喜欢使用typename,因为我不喜欢重载的关键字(天哪 - 对于各种不同的上下文有多少不同的含义?static
评论
typename
class
static
typename
template<class X> class Y { ...
typename
class
typename
class
typename
这完全无关紧要,但类使它看起来像 T 只能是一个类,而它当然可以是任何类型。所以 typename 更准确。另一方面,大多数人使用类,因此通常可能更容易阅读。
评论
class
typename
typename
class
typename
class
typename
class
typename
typename
class
typename
作为对 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 代码的迹象。
评论
typename qwert::yuiop * asdfg;
typedef integer_traits<IntegerType> traits
扩展 DarenW 的评论。
一旦 typename 和 class 不被接受为非常不同,那么严格使用它们可能仍然有效。仅当确实是类时才使用 class,当它是基本类型(如 char)时才使用 typename。
这些类型确实也被接受,而不是 typename
模板< Char Myc = '/' >
在这种情况下,它甚至优于 typename 或 class。
想想“暗示”或对其他人的理解。实际上,考虑到第三方软件/脚本可能会尝试使用代码/信息来猜测模板发生了什么(考虑 swig)。
只是纯粹的历史。斯坦·李普曼(Stan Lippman)的引述:
这两个关键词的原因是历史性的。在最初的模板规范中,Stroustrup 重用了现有的 class 关键字来指定类型参数,而不是引入一个当然可能会破坏现有程序的新关键字。这并不是说没有考虑一个新关键词 - 只是考虑到它的潜在破坏,它被认为是没有必要的。在 ISO-C++ 标准之前,这是声明类型参数的唯一方法。
但是应该使用 typename 而不是 class! 有关详细信息,请参阅链接,但请考虑以下代码:
template <class T>
class Demonstration {
public:
void method() {
T::A *aObj; // oops ...
};
作为上述所有帖子的补充,在处理模板模板参数时,强制使用关键字(最多包括 C++14),例如:class
template <template <typename, typename> class Container, typename Type>
class MyContainer: public Container<Type, std::allocator<Type>>
{ /*...*/ };
在此示例中,将生成编译器错误,如下所示:typename Container
error: expected 'class' before 'Container'
评论
这是有区别的,你应该更喜欢.class
typename
但是为什么?
typename
对于模板模板参数是非法的,因此为了保持一致,您应该使用:class
template<template<class> typename MyTemplate, class Bar> class Foo { }; // :(
template<template<class> class MyTemplate, class Bar> class Foo { }; // :)
评论