在不需要时使用"template"和"typename"消除歧义器

Using "template" and "typename" disambiguators when they are not needed

本文关键字:typename 歧义 template 不需要      更新时间:2023-10-16

这个问题涵盖了C++模板代码中何时以及为什么需要typenametemplate消歧器。

在C++03中不需要这些消歧符的情况下使用这些消歧器有效吗?用C++11怎么样?

对于一些"有效"的定义,它在符合C++03/C++11编译器中是有效的

C++03 ISO/IEC 14882:2003§14.2.5:

[注意:typename前缀的情况一样,template前缀在非严格必要的情况下是允许的;即,当->.左侧的表达式,或嵌套名称说明符不依赖于模板参数时。]

C++11 ISO/IEC 14882:2011§14.2.5:

[注意:typename前缀的情况一样,template前缀在非严格必要的情况下是允许的;即,当嵌套名称说明符->.左侧的表达式不依赖于模板参数时,或者该用法不出现在模板的范围内。-尾注]

请注意,当有问题的成员实际上不是模板时,您不能使用template——您不允许对其撒谎。还要注意,对于typename,类型必须是限定的类型(例如X::Y,而不仅仅是X)。C++11也更改了它,这样你就不必在模板的范围内,而C++03要求你在模板中。还要注意的是,编译器可能会在是否真的允许执行这一操作上有所不同。例如,在Clang下,这会在标志-Wc++11-extensions下发出警告。


以下是一些例子,假设以下定义:

struct X {
    typedef int Y;
    template <typename T> static void foo();
    static void bar();
    template <typename T> static void baz(T);
};

在C++03和C++11:中都无效

template <typename T>
void foo() {
    typename int z = 0; // int is not a qualified name.
    X::template bar();  // X::bar is not a template.
    X::template baz(z); // no template argument list.
}

在C++03中无效,在C++11中有效(但在我的Clang副本上产生警告):

void bar() {
    typename X::Y z = 0;    // not in the body of a template, so
    X::template foo<int>(); // no possibility of dependent names.
}

在C++03和C++11:中都有效

template <typename T>
void baz() {
    typename X::Y z = 0;    // not a dependent name, so 'typename'
    X::template foo<int>(); // isn't strictly necessary.
}