简体   繁体   English

在这种特殊情况下,为什么C ++编译器需要“ typename”关键字?

[英]Why does the C++ compiler require a “typename” keyword in this particular case?

I just figured out that C++ requires a typename in the following code (see the member function definition at the end of the code fragment): 我刚刚发现C ++在以下代码中需要一个类型名(请参阅代码片段末尾的成员函数定义):

template <typename T> struct ClassWithSubtype
{
    struct Sub
    {
        //static void check( const ClassWithSubtype<T>::Sub& sub );
        ClassWithSubtype<T>::Sub& operator=( const ClassWithSubtype<T>::Sub& other );
    };
};

/*
//Here C++ does not require a typename for the argument type
template <typename T> void ClassWithSubtype<T>::Sub::check( const ClassWithSubtype<T>::Sub& sub )
{
    //do sth.
}
*/

//Here C++ requires a typename for the return type
template <typename T> typename ClassWithSubtype<T>::Sub& ClassWithSubtype<T>::Sub::operator=( const ClassWithSubtype<T>::Sub& other )
{
    //do sth.
}

I can completely understand that C++ requires the keyword typename for the return type. 我完全可以理解,C ++要求将关键字typename用作返回类型。 What I do not understand is why NO typename is needed for the argument type of the example function check (which is commented out). 我不明白的是为什么没有typename需要针对例如函数的参数类型check (这被注释掉)。 Furthermore, why is a typename required in the definition of the assignment operator, but not in its declaration? 此外,为什么一个typename在赋值运算符的定义要求,而不是在其声明?

These two rules together (both in 14.6.2.1) yield the observed behavior: 这两个规则(均在14.6.2.1中)共同产生了观察到的行为:

First, that 首先,

A name refers to the current instantiation if it is 名称是指当前实例,如果它是

  • in the definition of a class template, a nested class of a class template, a member of a class template, or a member of a nested class of a class template, the injected-class-name (Clause 9) of the class template or nested class, 在类模板,类模板的嵌套类,类模板的成员或类模板的嵌套类的成员的定义中,类模板的注入类名称 (第9条)或嵌套类

  • in the definition of a primary class template or a member of a primary class template, the name of the class template followed by the template argument list of the primary template (as described below) enclosed in <> (or an equivalent template alias specialization), 在定义主类模板或主类模板的成员时,类模板的名称后跟<>包含的主模板的模板参数列表(如下所述)(或等效的模板别名专门化) ,

  • in the definition of a nested class of a class template, the name of the nested class referenced as a member of the current instantiation, or 在类模板的嵌套类的定义中,嵌套类的名称被引用为当前实例的成员,或者

and one more unrelated bullet point. 还有一个不相关的要点。

Then, 然后,

A name is a member of the current instantiation if it is 名称是当前实例的成员,如果它是

  • An unqualified name that, when looked up, refers to at least one member of a class that is the current instantiation or a non-dependent base class thereof. 一种不合格的名称,当查找时,它指的是该类的至少一个成员,该类是当前实例或其非依赖基类。 [ Note: This can only occur when looking up a name in a scope enclosed by the definition of a class template. [注意: 仅当在类模板的定义所包围的范围内查找名称时,才会发生这种情况。 — end note ] —尾注]

and two unrelated bullet points. 和两个无关的要点。

Therefore, in both cases, ClassWithSubType<T> refers to the current instantiation. 因此,在两种情况下, ClassWithSubType<T>引用当前实例。 But as the note explains, Sub refers to a member of the current instantiation only when used inside the class template body. 但是正如注释所解释的, Sub仅在类模板主体中使用时才引用当前实例的成员。 In the out-of-class definition, it becomes a "member of an unknown specialization". 在类外定义中,它成为“未知专业化的成员”。

As a member of the current instantiation, the compiler determines that Sub is a class type. 作为当前实例的成员,编译器确定Sub是类类型。

Outside the class body, the compiler doesn't know this and the typename keyword is needed. 在类主体之外,编译器不知道这一点,因此需要typename关键字。

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

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