Mat*_*Mat 456 c++ templates keyword
对于模板,我看到了两个声明:
template < typename T >
template < class T >
Run Code Online (Sandbox Code Playgroud)
有什么不同?
这些关键字在下面的例子中究竟是什么意思(取自德国维基百科关于模板的文章)?
template < template < typename, typename > class Container, typename Type >
class Example
{
Container< Type, std::allocator < Type > > baz;
};
Run Code Online (Sandbox Code Playgroud)
Aar*_*otz 401
typename
并且class
在指定模板的基本情况下可以互换:
template<class T>
class Foo
{
};
Run Code Online (Sandbox Code Playgroud)
和
template<typename T>
class Foo
{
};
Run Code Online (Sandbox Code Playgroud)
是等价的.
话虽如此,有些特定情况下typename
和之间存在差异class
.
第一个是依赖类型的情况.typename
用于在引用依赖于另一个模板参数的嵌套类型时声明,例如typedef
在此示例中:
template<typename param_t>
class Foo
{
typedef typename param_t::baz sub_t;
};
Run Code Online (Sandbox Code Playgroud)
你在问题中实际显示的第二个,尽管你可能没有意识到:
template < template < typename, typename > class Container, typename Type >
Run Code Online (Sandbox Code Playgroud)
在指定模板模板时,class
必须按上述方式使用关键字 - 在这种情况下它不可互换(注意:由于C++ 17在这种情况下允许两个关键字).typename
您还必须class
在显式实例化模板时使用:
template class Foo<int>;
Run Code Online (Sandbox Code Playgroud)
我确信还有其他一些我错过的情况,但最重要的是:这两个关键字并不相同,而且这些是您需要使用其中一个的常见情况.
Geo*_*che 87
用于命名模板参数,typename
并且class
是等效的.§14.1.2:
template-parameter中的class和typename之间没有语义差异.
typename
但是在使用模板时可能在另一个上下文中 - 提示您正在引用依赖类型的编译器.§14.6.2:
假定模板声明或定义中使用的名称以及依赖于模板参数的名称不会命名类型,除非适用的名称查找找到类型名称或名称由关键字typename限定.
例:
typename some_template<T>::some_type
Run Code Online (Sandbox Code Playgroud)
没有typename
编译器一般不能告诉你是否指的是类型.
Mic*_*son 22
虽然没有技术差异,但我看到这两个用来表示略有不同的东西.
对于应该接受任何类型为T的模板,包括内置函数(如数组)
template<typename T>
class Foo { ... }
Run Code Online (Sandbox Code Playgroud)
对于仅在T是真实类的情况下才能工作的模板.
template<class T>
class Foo { ... }
Run Code Online (Sandbox Code Playgroud)
但请记住,这纯粹是一些人使用的风格.不是由标准强制要求或由编译器强制执行
小智 9
<typename T>
使用OR之间没有区别<class T>
;即它是 C++ 程序员使用的约定。我自己更喜欢它<typename T>
,因为它更清楚地描述了它的用途;即定义具有特定类型的模板。
注意:有一个例外,在声明模板模板参数时,您必须使用class
(而不是):typename
template <template <typename> class T> class C { }; // valid!
template <template <typename> typename T> class C { }; // invalid!
Run Code Online (Sandbox Code Playgroud)
在大多数情况下,您不会定义嵌套模板定义,因此任一定义都可以工作——只需在使用中保持一致即可。
Container
本身是具有两个类型参数的模板.
这段代码来自c ++入门书。虽然我确定这是错误的。
每个类型参数必须以关键字class或typename开头:
// error: must precede U with either typename or class
template <typename T, U> T calc(const T&, const U&);
Run Code Online (Sandbox Code Playgroud)
这些关键字具有相同的含义,可以在模板参数列表中互换使用。模板参数列表可以同时使用两个关键字:
// ok: no distinction between typename and class in a template parameter list
template <typename T, class U> calc (const T&, const U&);
Run Code Online (Sandbox Code Playgroud)
使用关键字typename而不是使用class来指定模板类型参数似乎更直观。毕竟,我们可以将内置(非类)类型用作模板类型参数。此外,typename更清楚地指示后面的名称是类型名称。但是,在模板已经广泛使用之后,typename被添加到C ++中。一些程序员继续专门使用类
归档时间: |
|
查看次数: |
133123 次 |
最近记录: |