c - 使用'class'或者'typename'为模板参数?

  显示原文与译文双语对照的内容

可能重复:
C++ 中关键字'typename'和'类'的差异

在 C++ 中定义函数模板或者类模板时,可以编写:


template <class T>.. .

或者你可以写:


template <typename T>.. .

是否有一个更好的理由比另一个更好?


我接受了最受欢迎的( 还有有趣的) 回答,但真正的答案似乎是"不,没有理由喜欢一种类型。"

  • 它们是等价的( 除了下面提到的) 。
  • 有些人总是使用 typename的原因。
  • 有些人总是使用 class的原因。
  • 有些人有使用两者的理由。
  • 有些人不关心他们使用哪一个。

但是,在模板模板模板参数的情况下,需要使用 class 而不是 typename 。 看到下面的user1428839回答。(但这种特殊情况下不是一种偏好,它是语言的一种需求。)

时间:

斯坦Lippman在这里谈论了这个 我觉得这很有趣。

。: Stroustrup最初使用 class 来指定模板中的类型以避免引入新关键字。 委员会中的一些人担心这个关键词的重载导致混乱。 随后,委员会引入了一个新的关键字 typename 来解决语法错误,并决定使用它来指定模板类型以减少混淆,但为了减少混淆,class 保留了它的重载含义。

作为上所有文章的补充,使用 class 关键字 处理时强制 模板模板 参数,e.g.:


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

在本例中,typename Container 会生成一个编译器错误,如下所示:


error: expected 'class' before 'Container'

回应迈克b,我更喜欢使用'类', 在一个模板,'typename'重载的意思,但'类'并非如此。 接受这个选中的整数类型示例:


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'来进行 preceed,以便解析器能够识别 larger_integer_t 是一个类型。 otherhand,没有这样的重载的意思。

那个。。或者我只是 lazy 。 我键入'类'的频率比'typename'多,因此更容易输入。 或者可能是我写过太多的OO代码。

纯粹的历史。 Lippman的名言:

这两个关键字的原因是历史。 在原始模板规范中,Stroustrup重用了现有的类关键字来指定类型参数,而不是引入可能会破坏现有程序的新关键字。 不是一个新的关键字被认为是 --,因为它没有考虑到它潜在的中断。 在ISO-C++标准之前,这是声明类型参数的唯一方法。

但是每个人都应该使用 typename而不是 ! 查看链接以获得更多信息,但请考虑以下代码:


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

是有区别的,你应该更喜欢 classtypename

但是为什么?

typename 对于模板模板参数非法,因此要保持一致,你应该使用 class:


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

...