简体   繁体   English

在嵌套名称说明符中使用简单模板 ID 是否明确表示 class 模板专业化?

[英]Does the use a simple-template-id in a nested-name-specifier unambiguously mean a class template specialization?

struct A{
    template<typename U>
    void T(){}
};
struct B{
    template<typename U>
    struct T{
       using type = U;
    };
};
struct C:A,B{

};
int main(){
    C::T<int>::type d;
}

This example is accepted by neither GCC nor Clang. GCC 和 Clang 均不接受此示例

As per basic.lookup.qual#1根据basic.lookup.qual#1

The name of a class or namespace member or enumerator can be referred to after the:: scope resolution operator ([expr.prim.id.qual]) applied to a nested-name-specifier that denotes its class, namespace, or enumeration. class 或命名空间成员或枚举器的名称可以在:: scope 解析运算符 ([expr.prim.id.qual]) 后引用,该解析运算符 ([expr.prim.id.qual]) 应用于表示其 ZA2F2ED4F8EBC2CBB4C21、命名空间或 enDCum 的嵌套名称说明符If a:: scope resolution operator in a nested-name-specifier is not preceded by a decltype-specifier, lookup of the name preceding that:: considers only namespaces, types, and templates whose specializations are types .如果嵌套名称说明符中的 a:: scope 解析运算符前面没有 decltype-说明符,则查找前面的名称::仅考虑其特化为 types 的名称空间、类型和模板

That means that when looking up the declarations for the template name T , the specialization of T shall denote a type in this context.这意味着在查找模板名称T的声明时, T的特化应表示此上下文中的类型。 On the other hand, as perclass.member.lookup#4另一方面,根据class.member.lookup#4

If C contains a declaration of the name f, the declaration set contains every declaration of f declared in C that satisfies the requirements of the language construct in which the lookup occurs .如果 C 包含名称 f 的声明,则声明集包含在 C 中声明的每个满足查找发生的语言构造要求的f 声明。

Again, when looking up the template T in the scope of C , only those templates whose specialization is a type should be considered by this lookup.同样,当在 C 的C中查找模板T时,此查找应仅考虑那些特化为类型的模板。 The scope of C does not have any declarations for T , hence the lookup will be performed for S(T,C) in every one of its base classes. C 的C没有任何T声明,因此将在其每个基类中对S(T,C)执行查找。 The template T in A does not satisfy the requirement. A中的模板T不满足要求。 Meanwhile, the template T declared in the scope of B does satisfy the requirement.同时, B的 scope 中声明的模板T确实满足要求。 So the lookup is not ambiguous and the B::T is the unique result.所以查找不是模棱两可的, B::T是唯一的结果。 That means C::T<int>::type d should be well-formed.这意味着C::T<int>::type d应该格式正确。 Why do both GCC and Clang reject this example?为什么 GCC 和 Clang 都拒绝这个例子? Can it be considered a bug of in both?它可以被认为是两者的错误吗? If I missed something, what's the reason that this example should be ill-formed?如果我遗漏了什么,那么这个例子不正确的原因是什么?

The lookahead required to have the lookup for T depend on the :: even as the interpretation of < depends on the meaning of T is considered undesirable.查找T所需的前瞻取决于::即使对<的解释取决于T的含义被认为是不可取的。 As such, lookup for a name followed by < is not restricted to types and namespaces regardless of any >:: found later.因此,查找后跟<的名称不限于类型和命名空间,无论以后找到任何>:: P1787R6 fixed this, restricting the special lookup to identifiers immediately followed by :: (since other kinds of names can't refer to types or namespaces anyway). P1787R6修复了这个问题,将特殊查找限制为紧跟::的标识符(因为其他类型的名称无论如何都不能引用类型或命名空间)。

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

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