"typename"和"template"关键字:他们真的有必要吗?

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++标准对此有何看法.

Pau*_*ans 6

规则是: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,编译器不知道<令牌不是小于但是模板参数列表的开头.