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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/213121/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 13:45:46  来源:igfitidea点击:

Use 'class' or 'typename' for template parameters?

c++templates

提问by Kristopher Johnson

Possible Duplicate:
C++ difference of keywords ‘typename' and ‘class' in templates

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

When defining a function template or class template in C++, one can write this:

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

template <class T> ...

or one can write this:

或者可以这样写:

template <typename T> ...

Is there a good reason to prefer one over the other?

是否有充分的理由偏爱其中之一?



I accepted the most popular (and interesting) answer, but the real answer seems to be "No, there is no good reason to prefer one over the other."

我接受了最受欢迎(和有趣)的答案,但真正的答案似乎是“不,没有充分的理由偏爱其中一个”。

  • They are equivalent (except as noted below).
  • Some people have reasons to always use typename.
  • Some people have reasons to always use class.
  • Some people have reasons to use both.
  • Some people don't care which one they use.
  • 它们是等效的(除非如下所述)。
  • 有些人有理由总是使用typename.
  • 有些人有理由总是使用class.
  • 有些人有理由同时使用两者。
  • 有些人不在乎他们使用哪一种。

Note, however, that before C++17 in the case of template templateparameters, use of classinstead of typenamewas required. See user1428839's answerbelow. (But this particular case is not a matter of preference, it was a requirement of the language.)

但是请注意,在 C++17 之前,在模板模板参数的情况下,需要使用class代替typename。请参阅下面的user1428839 的回答。(但这种特殊情况不是偏好问题,而是语言的要求。)

采纳答案by itsmatt

Stan Lippman talked about this here. I thought it was interesting.

斯坦利普曼在这里谈到了这一点。我觉得这很有趣。

Summary: Stroustrup originally used classto specify types in templates to avoid introducing a new keyword. Some in the committee worried that this overloading of the keyword led to confusion. Later, the committee introduced a new keyword typenameto resolve syntactic ambiguity, and decided to let it also be used to specify template types to reduce confusion, but for backward compatibility, classkept its overloaded meaning.

总结:Stroustrup 最初用于class在模板中指定类型以避免引入新关键字。委员会中的一些人担心关键字的这种超载会导致混淆。后来,委员会引入了一个新的关键字typename来解决句法歧义,并决定让它也用于指定模板类型以减少混淆,但为了向后兼容,class保留其重载的含义。

回答by DarenW

According to Scott Myers, Effective C++ (3rd ed.) item 42 (which must, of course, be the ultimate answer) - the difference is "nothing".

根据 Scott Myers 的说法,Effective C++(第 3 版)第 42 项(当然,这必须是最终答案)——区别在于“没有”。

Advice is to use "class" if it is expected T will always be a class, with "typename" if other types (int, char* whatever) may be expected. Consider it a usage hint.

建议是,如果预期 T 将始终是一个类,则使用“class”,如果可能预期其他类型(int、char* 等),则使用“typename”。将其视为使用提示。

回答by JorenHeit

As an addition to all above posts, the use of the classkeyword isforced (up to and including C++14) when dealing with template templateparameters, e.g.:

作为除了所有上述职位,使用的class关键字被迫(直至并包括C ++ 14),当处理模板的模板的参数,例如:

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

In this example, typename Containerwould have generated a compiler error, something like this:

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

error: expected 'class' before 'Container'

回答by Michael Burr

I prefer to use typename because I'm not a fan of overloaded keywords (jeez - how many different meanings does statichave for various different contexts?).

我更喜欢使用 typename 因为我不喜欢重载关键字(天啊 -static对于各种不同的上下文有多少不同的含义?)。

回答by user541686

There isa difference, and you should prefer classto typename.

这里一个区别,你应该更喜欢classtypename

But why?

但为什么?

typenameis illegal for template template arguments, so to be consistent, you should use class:

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

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

回答by user541686

Just pure history. Quote from Stan Lippman:

只是纯粹的历史。引用斯坦·李普曼的名言

The reason for the two keywords is historical. In the original template specification, Stroustrup reused the existing class keyword to specify a type parameter rather than introduce a new keyword that might of course break existing programs. It wasn't that a new keyword wasn't considered -- just that it wasn't considered necessary given its potential disruption. And up until the ISO-C++ standard, this was the only way to declare a type parameter.

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

But one should use typenamerather than class! See the link for more info, but think about the following code:

但是应该使用typename而不是class!有关更多信息,请参阅链接,但请考虑以下代码:

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

回答by Aaron

In response to Mike B, I prefer to use 'class' as, within a template, 'typename' has an overloaded meaning, but 'class' does not. Take this checked integer type example:

在回应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_tis a dependent name, so it requires 'typename' to preceed it so that the parser can recognize that larger_integer_tis a type. class, on the otherhand, has no such overloaded meaning.

larger_integer_t是一个从属名称,因此它需要 'typename' 在它前面,以便解析器可以识别它larger_integer_t是一种类型。 另一方面,class没有这种重载的含义。

That... or I'm just lazy at heart. I type 'class' far more often than 'typename', and thus find it much easier to type. Or it could be a sign that I write too much OO code.

那……或者我只是内心很懒惰。我键入“class”的频率远高于“typename”,因此发现它更容易键入。或者这可能表明我写了太多 OO 代码。

回答by Frederik Slijkerman

It doesn't matter at all, but class makes it look like T can only be a class, while it can of course be any type. So typename is more accurate. On the other hand, most people use class, so that is probably easier to read generally.

完全没有关系,但是 class 使它看起来像 T 只能是一个类,而它当然可以是任何类型。所以 typename 更准确。另一方面,大多数人使用类,因此通常更容易阅读。

回答by Grant Limberg

As far as I know, it doesn't matter which one you use. They're equivalent in the eyes of the compiler. Use whichever one you prefer. I normally use class.

据我所知,您使用哪一种并不重要。它们在编译器眼中是等价的。使用您喜欢的任何一种。我通常使用类。

回答by muenalan

Extending DarenW's comment.

扩展 DarenW 的评论。

Once typename and class are not accepted to be very different, it might be still valid to be strict on their use. Use class only if is really a class, and typename when its a basic type, such as char.

一旦 typename 和 class 不被接受为非常不同,严格使用它们可能仍然有效。仅当真正是一个类时才使用 class,当它是一个基本类型时使用 typename,例如char

These types are indeed also accepted instead of typename

这些类型确实也被接受而不是typename

template< charmyc= '/' >

模板< char myc= '/'>

which would be in this case even superior to typename or class.

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

Think of "hintfullness" or intelligibility to other people. And actually consider that 3rd party software/scripts might try to use the code/information to guess what is happening with the template (consider swig).

想想“暗示”或对其他人的可理解性。实际上考虑到 3rd 方软件/脚本可能会尝试使用代码/信息来猜测模板发生了什么(考虑 swig)。