简体   繁体   English

在不需要时使用“template”和“typename”消歧器

[英]Using “template” and “typename” disambiguators when they are not needed

This question covers when and why the typename and template disambiguators are needed in C++ template code. 此问题涵盖了C ++模板代码中何时以及为何需要typenametemplate disambiguator。

Is it valid to use these disambiguators in cases where they are not needed in C++03? 在C ++ 03中不需要使用这些消歧器是否有效? How about in C++11? 在C ++ 11中怎么样?

It's valid in conforming C++03/C++11 compilers, for some definition of "valid." 它符合C ++ 03 / C ++ 11编译器的有效性,适用于“有效”的定义。

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

[ Note: just as is the case with the typename prefix, the template prefix is allowed in cases where it is not strictly necessary; [ 注意:就像typename前缀的情况一样,在不是绝对必要的情况下允许使用template前缀; ie, when the expression on the left of the -> or . 即,当表达式左侧的->. , or the nested-name-specifier is not dependent on a template-parameter . ,或嵌套名称说明符不依赖于模板参数 ] ]

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

[ Note: As is the case with the typename prefix, the template prefix is allowed in cases where it is not strictly necessary; [ 注意:typename前缀的情况一样,在不是绝对必要的情况下允许使用template前缀; ie, when the nested-name-specifier or the expression on the left of the -> or . 即,当嵌套名称说明符->或者左边的表达式时. is not dependent on a template-parameter , or the use does not appear in the scope of a template. 不依赖于模板参数 ,或者使用不会出现在模板的范围内。 end note ] - 结束说明 ]

Note that you can't use template when the member in question isn't actually a template—you aren't allow to lie with it. 请注意,当有问题的成员实际上不是template时,您无法使用template您不允许使用该模板。 Also note that for typename , the type has to be a qualified type (eg X::Y , not just X ). 另请注意,对于typename ,类型必须是限定类型(例如X::Y ,而不仅仅是X )。 C++11 also changed it so that you don't have to be in the scope of a template, whereas C++03 required you to be in a template. C ++ 11也改变了它,因此你不必在模板的范围内,而C ++ 03要求你在模板中。 Also note that compilers are likely to differ on whether they actually let you do this. 另请注意,编译器在实际上是否允许您这样做时可能会有所不同。 Under Clang, for instance, this warns under the flag -Wc++11-extensions . 例如,在Clang下,这会在标志-Wc++11-extensions下发出警告。


Here are some examples, assuming the following definition: 以下是一些示例,假设以下定义:

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

Invalid in both C++03 and C++11: 在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.
}

Invalid in C++03, valid in C++11 (but produces a warning on my copy of Clang): 在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.
}

Valid in both C++03 and C++11: 在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.
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM