注入的类名编译器不一致
Injected class name compiler discrepancy
考虑以下代码:
struct foo{};
int main() {
foo::foo a;
}
我希望这是格式良好的,根据[class]/2 (N4140,强调我的)中的规则声明类型为foo
的变量:
在类名出现后,立即将类名插入声明它的作用域。类名也被插入到类本身的作用域;这就是所谓的注入类名。出于访问检查的目的,注入的类名被视为公共成员名。
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
的错误?还是我对标准引用的解释不正确?
在这种情况下,clang
似乎是错误的。我正在寻找的相关异常在[class. quality]/2:
2函数名不被忽略且嵌套名称说明符指定类C的查找:
- 的注入类名,则
(2.1)如果在嵌套名称说明符后指定的名称在C中查找时是C或
[…]
这个名字被认为是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中存在此错误
相关,但不是答案:GCC人员多年来一直在讨论这个问题,并且认为它不应该被接受。在GCC 4.5和更新的版本中,他们明确地把这个错误变成了一个错误——在4.4.7中它被接受了。
BTW:你可能想用Clang的-Weverything
而不是-Wall -pedantic
来研究这些东西。
我认为这是语言缺陷#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似乎相信这一点。: -)
- 大于65535的C++数组[size]引发不一致的溢出
- decltype(1, t) 应该是 l 值引用吗?(编译器不同意)
- 在 C++(和 C)中进行类型转换时明显不一致
- 填充上编译器生成的复制构造函数之间的不一致
- 安装MinGW后C++编译器不起作用?
- 犰狳的 print() 方法和 cout 在从 Rcpp 调用时顺序不一致
- 编译器不会使用 -std=c++11 编译智能指针
- CreateDIBSection为同一图像返回不一致的位图位值
- 在 Qml 中从 QSqlTableModel 中删除单行时视图不一致
- 模板参数推导不一致
- 声明中不一致的no是否违反ODR?
- 为什么编译器不检查被覆盖函数的存储类?
- 如何删除分支因子不一致的树,最大为 30,40
- Clang编译器不支持aarch64-apple-darwin上的-fxray-instrument
- 从 C++ 函数与 Python 函数返回的不一致值用于偏斜正态分布
- 跨编译器的 constexpr 成员函数的重载解析不一致
- 编译器之间在丢弃的 if constexpr(false) 语句中实例化模板的行为不一致
- VS2015 编译器行为不一致
- 这种编译器优化不一致是否完全由未定义的行为来解释
- 注入的类名编译器不一致