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

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

template < typename T >
template < class T >

有什么不同?

在下面的例子中,这些关键词究竟意味着什么(摘自德国维基百科有关模板的文章)?

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

在指定模板的基本情况下, typenameclass是可以互换的:

template<class T>
class Foo
{
};

template<typename T>
class Foo
{
};

是等同的。

话虽如此,有些情况下typenameclass有区别。

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

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

第二个你真正在你的问题中展示,但你可能没有意识到:

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

在指定模板模板时 ,必须像上面那样使用class关键字 - 在这种情况下它不能typename互换(注意:因为在这种情况下允许使用C ++ 17两个关键字)。

明确实例化模板时还必须使用class

template class Foo<int>;

我相信还有其他一些我错过的例子,但底线是:这两个关键字不是等价的,而这些是一些常见的情况,您需要使用其中一个或另一个。


为了命名模板参数, typenameclass是等价的。 §14.1.2:

模板参数中的类和类型名称之间没有语义上的区别。

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

除非适用的名称查找找到类型名称或名称由关键字typename限定,否则假定在模板声明或定义中使用的名称取决于模板参数,而不是为类型命名。

例:

typename some_template<T>::some_type

如果没有typename那么编译器通常无法说明您是否指向某个类型。


虽然没有技术上的差异,但我看到这两个用来表示稍微不同的东西。

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

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

对于仅在T是真实类的地方才有效的模板。

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

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

链接地址: http://www.djcxy.com/p/37143.html

上一篇: Difference of keywords 'typename' and 'class' in templates?

下一篇: defining inline functions under template class definition