在嵌套名称说明符中使用 simple-template-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;
}
这个 example 既不被 GCC 也不被 Clang 接受。
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#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
的范围内查找模板 T
时,此查找只应考虑那些特化为类型的模板。 C
的作用域没有 T
的任何声明,因此将在其基数 类 中对 S(T,C)
执行查找。 A
中的模板T
不满足要求。同时,在 B
范围内声明的模板 T
确实满足要求。所以查找没有歧义, B::T
是唯一的结果。这意味着 C::T<int>::type d
应该是合式的。为什么 GCC 和 Clang 都拒绝这个例子?是否可以认为是两者的错误?如果我遗漏了什么,那么这个示例格式错误的原因是什么?
查找 T
所需的 lookahead 取决于 ::
即使 <
的解释取决于含义T
被认为是不受欢迎的。因此,查找后跟 <
的名称不限于类型和命名空间,而不管后面找到的任何 >::
。 P1787R6 修复了这个问题,将特殊查找限制为标识符 立即 后跟 ::
(因为其他类型的名称无论如何都不能引用类型或名称空间)。
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 接受。
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#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
的范围内查找模板 T
时,此查找只应考虑那些特化为类型的模板。 C
的作用域没有 T
的任何声明,因此将在其基数 类 中对 S(T,C)
执行查找。 A
中的模板T
不满足要求。同时,在 B
范围内声明的模板 T
确实满足要求。所以查找没有歧义, B::T
是唯一的结果。这意味着 C::T<int>::type d
应该是合式的。为什么 GCC 和 Clang 都拒绝这个例子?是否可以认为是两者的错误?如果我遗漏了什么,那么这个示例格式错误的原因是什么?
查找 T
所需的 lookahead 取决于 ::
即使 <
的解释取决于含义T
被认为是不受欢迎的。因此,查找后跟 <
的名称不限于类型和命名空间,而不管后面找到的任何 >::
。 P1787R6 修复了这个问题,将特殊查找限制为标识符 立即 后跟 ::
(因为其他类型的名称无论如何都不能引用类型或名称空间)。