gcc 是正确的;你的 sn-p 格式不正确!
// reduced testcase
template<class T>
class A { };
int main () {
A<float>::A<int> x; // ill-formed, bug in `clang` and `icc`
}
在上面简化的测试用例中,我们有一个 nested-name-specifier,A<float>::,后跟一个 unqualified-id A,然后是一些胡言乱语(<int>)。
这是因为 nested-name-specifier 出现的上下文要求在查找期间包含函数名称(意味着首先找到构造函数,并且表达式为格式错误)。
相关错误报告:
如何规避“问题”?
在某些上下文中,通过 nested-name-specifier(指定类)查找的成员名称不应包含函数(因此,找不到构造函数的上下文),下面是几个例子:
template<class T>
struct A {
typedef T value_type;
};
struct A<float>::A<int> x; // ok, context: elaborate-type-specifier
typename A<float>::A<int> (); // ok, context: [expr.type.conv]p1
A<float>::A::value_type x; // ok, context: nested-name-specifier
struct X : A<float>::A<int> { }; // ok, context: base-specifier
标准是怎么说的?
3.4.3.1p2 班级成员 [class.qual]
在不忽略函数名称的查找中88 并且 nested-name-specifier 指定了一个类 C:
- 如果在nested-name-specifier之后指定的名称,当在C中查找时,是C的注入类名>(第 9 条),或
- 在 using-declaration (7.3.3) 中,它是一个 member-declaration,如果在 nested-name-specifier 之后指定的名称 em> 与 *nested- 的最后一个组件中的 identifier 或 simple-template-id 的 template-name 相同名称说明符,
该名称被认为是命名类C的构造函数。
[ 注意: ... ]
这样的构造函数名称只能用于命名构造函数的声明的 declarator-id 或 using-declaration。
88. 忽略函数名称的查找包括出现在 nested-name-specifier 中的名称,elaborated-type-specifier,或 基本说明符。
14.6.1p2 本地声明的名称 [temp.local]
与普通(非模板)类一样,类模板具有注入的类名
(第 9 条)。注入的类名可以用作 template-name 或
类型名称。
当它与 template-argument-list 一起使用时,作为
template-argument 用于模板 template-parameter,或作为最终
朋友类模板的详细类型说明符中的标识符
声明,它引用类模板本身。
否则就是
相当于 template-name 后跟 template-parameters
<> 中包含的类模板。