考虑下面的代码:
struct foo{};
int main() {
foo::foo a;
}
我希望这是格式良好的,通过class/2中的规则声明了一个foo
类型的变量(N4140,重点是我的):
在看到类名之后立即将类名插入到声明它的作用域中。类名也被插入到类本身的作用域中;这称为注入类名。出于访问检查的目的,注入的类名被视为公共成员名。
clang 3.6.0
同意我的观点,他用-Wall -pedantic
编译了上面的代码,没有适用的警告。
gcc 5.2.0
不同意,并提供了以下错误消息:
main.cpp: In function 'int main()':
main.cpp:5:5: error: 'foo::foo' names the constructor, not the type
foo::foo a;
无论注入的类名的嵌套有多深,例如foo::foo::foo::foo
,以上都是成立的。
是否存在强制将该构造解释为该上下文中的构造函数的规则,或者这是一个gcc
错误?或者我对标准引用的解释不正确?
发布于 2015-08-14 17:39:49
在这种情况下,clang
似乎是错误的。我正在寻找的相关异常在class.qual/2中:
在不忽略函数名的查找中使用
2,并且嵌套名称说明符指定一个类C:
如果在C中查找时,在嵌套名称说明符之后指定的名称是C
的注入类名称,则为嵌套名称(2.1)
作为替代,将该名称视为类C的构造函数的名称。
该标准有一个几乎等效的(显然是非标准化的)示例:
struct A { A(); };
struct B: public A { B(); };
A::A() { }
B::B() { }
B::A ba;// object of type A
A::A a;// error, A::A is not a type name
struct A::A a2;// object of type A
但是,在这种情况下,clang
实际上会发出正确的诊断:
error: qualified reference to 'A' is a constructor name rather than a type wherever a constructor can be declared
也许clang
将行In a lookup in which function names are not ignored
解释为In a lookup in which a constructor declaration is valid
,但这似乎不是一个正确的解释。
在clang
bugzilla中有一个用于此的existing bug。
发布于 2015-08-14 17:15:39
发布于 2015-08-14 17:13:18
我认为这就是包含以下示例的language defect #147的主题
class B { };
class A: public B {
A::B ab; // B is the inherited injected B
A::A aa; // Error: A::A is the constructor
};
至少,gcc似乎相信这一点。:-)
https://stackoverflow.com/questions/32006122
复制相似问题