本文翻译自:Difference of keywords 'typename' and 'class' in templates?
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)? 在下面的示例中这些关键字到底是什么意思(摘自关于模板的Wikipedia文章)?
template < template < typename, typename > class Container, typename Type >
class Example
{
Container< Type, std::allocator < Type > > baz;
};
#1楼
参考:https://stackoom.com/question/8UWn/模板中关键字-typename-和-class-的区别
#2楼
This piece of snippet is from c++ primer book. 这段代码来自c ++入门书。 Although I am sure this is wrong. 虽然我确定这是错误的。
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. 使用关键字typename而不是使用类来指定模板类型参数似乎更直观。 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. 此外,typename更清楚地指示后面的名称是类型名称。 However, typename was added to C++ after templates were already in widespread use; 但是,在模板已经广泛使用之后,typename被添加到C ++中。 some programmers continue to use class exclusively 一些程序员继续专门使用类
#3楼
- No difference 没有不同
- Template type parameter
Container
is itself a template with two type parameters. 模板类型参数Container
本身就是带有两个类型参数的模板。
#4楼
For naming template parameters, typename
and class
are equivalent. 对于命名模板参数, typename
和class
是等效的。 §14.1.2: 第14.1.2条:
There is no semantic difference between class and typename in a template-parameter. 模板参数中的类和类型名之间没有语义上的区别。
typename
however is possible in another context when using templates - to hint at the compiler that you are referring to a dependent type. 但是,在使用模板的另一个上下文中,可以使用typename
提示编译器您引用的是依赖类型。 §14.6.2: 第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 typename
the compiler can't tell in general whether you are referring to a type or not. 没有typename
,编译器通常不会告诉您是否在引用类型。
#5楼
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的模板,包括内置函数(例如array)
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 未由标准强制要求或由编译器强制执行
#6楼
typename
and class
are 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 typename
and class
. 话虽如此,在特定情况下, typename
和class
有所不同。
The first one is in the case of dependent types. 第一个是在依赖类型的情况下。 typename
is used to declare when you are referencing a nested type that depends on another template parameter, such as the typedef
in 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 class
keyword MUST be used as above -- it is not interchangeable with typename
in this case (note: since C++17 both keywords are allowed in this case) . 指定模板模板时 ,必须按上述方式使用class
关键字-在这种情况下,它不能与typename
互换(注意:由于C ++ 17,在这种情况下,两个关键字都允许) 。
You also must use class
when 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. 我确定还有其他情况,但是最重要的是:这两个关键字不相同,这是一些您需要使用其中一个的常见情况。