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

本文翻译自: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楼

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

#4楼

For naming template parameters, typename and class are equivalent. 对于命名模板参数, typenameclass是等效的。 §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: 在指定模板的基本情况下, typenameclass可互换:

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 . 话虽如此,在特定情况下, typenameclass有所不同。

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. 我确定还有其他情况,但是最重要的是:这两个关键字不相同,这是一些您需要使用其中一个的常见情况。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值