C++ 模板中关键字“typename”和“class”的区别?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2023977/
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 21:51:37  来源:igfitidea点击:

Difference of keywords 'typename' and 'class' in templates?

c++templateskeyword

提问by Mat

For templates I have seen both declarations:

对于模板,我已经看到了两个声明:

template < typename T >
template < class T >

What's the difference?

有什么不同?

And what exactly do those keywords mean in the following example (taken from the German Wikipedia article about templates)?

在下面的例子中这些关键字到底是什么意思(取自德语维基百科关于模板的文章)?

template < template < typename, typename > class Container, typename Type >
class Example
{
     Container< Type, std::allocator < Type > > baz;
};

采纳答案by Aaron Klotz

typenameand classare interchangeable in the basic case of specifying a template:

typename并且class在指定模板的基本情况下可以互换:

template<class T>
class Foo
{
};

and

template<typename T>
class Foo
{
};

are equivalent.

是等价的。

Having said that, there are specific cases where there is a difference between typenameand class.

话虽如此,在某些特定情况下,typename和之间存在差异class

The first one is in the case of dependent types. typenameis used to declare when you are referencing a nested type that depends on another template parameter, such as the typedefin this example:

第一个是在依赖类型的情况下。typename用于在引用依赖于另一个模板参数的嵌套类型时声明,例如typedef本示例中的 :

template<typename param_t>
class Foo
{
    typedef typename param_t::baz sub_t;
};

The second one you actually show in your question, though you might not realize it:

您实际上在问题中显示的第二个,尽管您可能没有意识到:

template < template < typename, typename > class Container, typename Type >

When specifying a template template, the classkeyword MUST be used as above -- it is notinterchangeable with typenamein this case (note: since C++17 both keywords are allowed in this case).

当指定模板 template 时class关键字必须如上使用——在这种情况下它不能与 互换(注意:因为 C++17 在这种情况下允许使用这两个关键字)typename

You also must use classwhen explicitly instantiating a template:

您还必须class在显式实例化模板时使用:

template class Foo<int>;

I'm sure that there are other cases that I've missed, but the bottom line is: these two keywords are not equivalent, and these are some common cases where you need to use one or the other.

我确信还有其他一些情况我错过了,但最重要的是:这两个关键字并不等效,而且这些是您需要使用其中一个的一些常见情况。

回答by Georg Fritzsche

For naming template parameters, typenameand classare equivalent. §14.1.2:

用于命名模板参数,typename并且class是等价的。第 14.1.2 节:

There is no semantic difference between class and typename in a template-parameter.

模板参数中的 class 和 typename 之间没有语义差异。

typenamehowever is possible in another context when using templates - to hint at the compiler that you are referring to a dependent type. §14.6.2:

typename然而,在使用模板时在另一个上下文中是可能的 - 向编译器暗示您指的是依赖类型。第 14.6.2 节:

A name used in a template declaration or definition and that is dependent on a template-parameter is assumed not to name a type unless the applicable name lookup finds a type name or the name is qualified by the keyword typename.

模板声明或定义中使用且依赖于模板参数的名称被假定为不命名类型,除非适用的名称查找找到类型名称或名称由关键字 typename 限定。

Example:

例子:

typename some_template<T>::some_type

Without typenamethe compiler can't tell in general whether you are referring to a type or not.

没有typename编译器一般无法判断您是否指的是类型。

回答by Michael Anderson

While there is no technical difference, I have seen the two used to denote slightly different things.

虽然没有技术上的区别,但我已经看到这两者用于表示略有不同的事物。

For a template that should accept any type as T, including built-ins (such as an array )

对于应该接受任何类型作为 T 的模板,包括内置函数(例如数组)

template<typename T>
class Foo { ... }

For a template that will only work where T is a real class.

对于仅在 T 是真正类的情况下才有效的模板。

template<class T>
class Foo { ... }

But keep in mind that this is purely a style thing some people use. Not mandated by the standard or enforced by compilers

但请记住,这纯粹是某些人使用的一种风格。标准未强制要求或编译器强制执行

回答by Nikolai Fetissov

  1. No difference
  2. Template type parameter Containeris itself a template with two type parameters.
  1. 没有不同
  2. 模板类型参数Container本身就是一个带有两个类型参数的模板。

回答by K.K

This piece of snippet is from c++ primer book. Although I am sure this is wrong.

这段代码来自 c++ 入门书。虽然我确信这是错误的。

Each type parameter must be preceded by the keyword class or typename:

每个类型参数必须以关键字 class 或 typename 开头:

// error: must precede U with either typename or class
template <typename T, U> T calc(const T&, const U&);

These keywords have the same meaning and can be used interchangeably inside a template parameter list. A template parameter list can use both keywords:

这些关键字具有相同的含义,可以在模板参数列表中互换使用。模板参数列表可以使用两个关键字:

// ok: no distinction between typename and class in a template parameter list
template <typename T, class U> calc (const T&, const U&);

It may seem more intuitive to use the keyword typename rather than class to designate a template type parameter. After all, we can use built-in (nonclass) types as a template type argument. Moreover, typename more clearly indicates that the name that follows is a type name. However, typename was added to C++ after templates were already in widespread use; some programmers continue to use class exclusively

使用关键字 typename 而不是 class 来指定模板类型参数似乎更直观。毕竟,我们可以使用内置(非类)类型作为模板类型参数。而且,typename 更清楚地表明后面的名称是一个类型名称。然而,在模板已经广泛使用之后,typename 被添加到 C++ 中;一些程序员继续专门使用类