[英]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.