使用“class”或“typename”作为模板参数?

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

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

template <class T> ... 

或者可以这样写:

 template <typename T> ... 

有一个比另一个更好的理由吗?


我接受了最stream行(也是最有意思)的答案,但真正的答案似乎是“不,没有理由相互优先select”。

  • 它们是相同的(除非如下所述)。
  • 有些人有理由总是使用typename
  • 有些人有理由一直使用class
  • 有些人有理由同时使用。
  • 有些人不在乎他们使用哪一个。

但是,请注意,在模板模板参数的情况下,需要使用class而不是typename 。 请参阅下面的user1428839的答案 。 (但这个特殊情况并不是偏好问题,而是语言的一个要求。)(这也会随着c++17变化而变化)

斯坦·李普曼在这里谈到了这一点 。 我认为这很有趣。

总结 :Stroustrup最初使用class来指定模板中的types,以避免引入新的关键字。 委员会中的一些人担心这个关键字的超载导致了混淆。 之后,委员会引入了一个新的关键字typename来解决语义上的歧义,并决定让它用来指定模板types以减less混淆,但为了向后兼容, class保持其超载的含义。

根据斯科特·迈尔斯(Scott Myers)的说法,Effective C ++(第3版)第42项(当然必须是最终的答案) – 区别是“没有”。

build议是使用“类”如果预期T将永远是一个类,与“types名”如果其他types(INT,CHAR *无论)可能是预期的。 考虑一下使用提示。

作为上述所有post的补充,在处理模板模板参数时强制使用class关键字( 编辑:最多包括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' 

请参阅http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4051.html,了解在C ++ 14中模板模板中是否接受typename。

我更喜欢使用typename,因为我不是超载关键字的粉丝(jeez – 对于各种不同的上下文, static有多less不同的含义?)。

有一个区别,你应该喜欢classtypename

但为什么?

typename对于模板模板参数是非法的,所以为了保持一致,你应该使用class

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

为了回应Mike B ,我更喜欢使用'class',因为在模板中,'typename'具有重载意义,但'class'不是。 以这个检查整数types的例子:

 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是一个独立的名称,所以它需要在其larger_integer_t “typename”,以便parsing器可以识别出larger_integer_t是一个types。 另一方面,这个没有这样的重载意义。

那…或者我只是懒惰的内心。 我比'typename'更经常地键入'class',因此更容易input。 或者这可能是我写了太多面向对象代码的标志。

根本不重要,但是class级看起来像T只能是一个class级,当然可以是任何types的class级。 所以typename更准确。 另一方面,大多数人使用类,所以一般来说可能更容易阅读。

只是纯粹的历史。 引自Stan Lippman :

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

但是应该使用typename而不是class ! 查看链接了解更多信息,但请考虑以下代码:

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

据我所知,你使用哪一个并不重要。 在编译器的眼中,它们是相同的。 使用你喜欢的任何一个。 我通常使用类。

扩展DarenW的评论。

一旦typename和class不被接受是非常不同的,严格使用它可能仍然是有效的。 使用类只有当它是一个基本的types,如char

这些types确实也被接受,而不是typename

模板< char myc ='/'>

在这种情况下甚至会优于typename或class。

想一下“hintfullness”或其他人的可理解性。 并且实际上考虑第三方软件/脚本可能会尝试使用代码/信息来猜测模板发生了什么(考虑swig)。