Con*_*tor 4 c++ templates keyword typename c++11
在编译c ++模板代码时,此站点上存在许多问题.解决此类问题的最常见方法之一是在程序代码的正确位置添加typename(并且不常使用template)关键字:
template<typename T>
class Base
{
public:
typedef char SomeType;
template<typename U>
void SomeMethod(SomeType& v)
{
// ...
}
};
template<typename T>
class Derived : public Base<T>
{
public:
void Method()
{
typename Base<T>::SomeType x;
// ^^^^^^^^
this->template SomeMethod<int>(x);
// ^^^^^^^^
}
};
Run Code Online (Sandbox Code Playgroud)
是否存在使用和不使用关键字编译的代码typename并给出不同的结果(例如输出字符串)?template关键字的类似问题.
如果没有,这些关键词是否真的有必要?
@Paul Evans写了一个很好的答案,但它更适合于 "我在哪里以及为什么要放置"模板"和"typename"关键字?" ,不是我的问题.
@simple给出的示例所需的代码为typename关键字和它的可能的变化.@ Jarod42给出了另一个没有任何模板的变体,这可能是一个 gcc bug,因为它不能用clang编译.
@nm给出了关键字所需代码template的示例, @ dyp 改进了它.@nm还使用 SFINAE 为这两个关键字编写了另一个代码.
@James Kanze在他的回答中指出,编写所需的代码是不可能的,任何尝试这样做都会导致未定义的行为.所以上面的代码示例是非法的.
有趣的是找出谁是对的以及C++标准对此有何看法.
规则是:typename 必须在依赖于模板参数的名称是类型时使用.考虑到有需要的明显案例
template <typename T>
class Foo {
typename T::type * p;
//...
};
Run Code Online (Sandbox Code Playgroud)
这里,第二个typename用于表示type是在其中定义的类型class T.因此,p是指向该类型的指针T::type.
没有typename,type将被视为成员class T.所以表达式:
T::type * p
Run Code Online (Sandbox Code Playgroud)
将是一个乘法type的构件class T用p.
同样,规则是:.template,->template或者在访问使用模板参数的模板成员时::template 必须使用该规则.考虑:
p->template SomeMethod<int>(x);
Run Code Online (Sandbox Code Playgroud)
在没有使用的情况下template,编译器不知道<令牌不是小于但是模板参数列表的开头.