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;
}
此 example GCC 和 Clang 都不接受。根据 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. 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.
这意味着在查找模板名称
T
的声明时,专精T
在此上下文中应表示一种类型。另一方面,根据 class.member.lookup#4If 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.
同样,在查找模板时
T
在C
范围内,此查找仅应考虑那些专门化为类型的模板。 C
范围T
没有任何声明,因此将为 S(T,C)
执行查找在它的每一个基类中。模板T
在 A
不满足要求。同时,模板T
在 B
的范围内声明确实满足要求。所以查找没有歧义,B::T
是唯一的结果。这意味着 C::T<int>::type d
应该是良构的。为什么 GCC 和 Clang 都拒绝这个例子?它可以被认为是两者的错误吗?如果我错过了什么,这个例子应该格式错误的原因是什么?
最佳答案
前瞻需要查找 T
取决于 ::
偶为解读<
取决于T
的含义被认为是不受欢迎的。因此,查找名称后跟 <
不受类型和命名空间的限制,无论任何 >::
后来发现。 P1787R6修复了这个问题,将特殊查找限制为标识符 立即其次是 ::
(因为其他类型的名称无论如何都不能引用类型或命名空间)。
关于c++ - 在嵌套名称说明符中使用 simple-template-id 是否明确表示类模板特化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66383078/