作为我上一个问题的一个有趣的后续行动(尽管实际上并不重要): Why does C++ allow us to surround the variable name in parentheses when declaring a variable?
我发现将括号中的声明与 injected class name 结合起来功能可能会导致关于编译器行为的令人惊讶的结果。
看看下面的程序:
#include <iostream>
struct B
{
};
struct C
{
C (){ std::cout << "C" << '\n'; }
C (B *) { std::cout << "C (B *)" << '\n';}
};
B *y = nullptr;
int main()
{
C::C (y);
}
使用 g++ 4.9.2 编译时出现以下编译错误:
main.cpp:16:10: error: cannot call constructor 'C::C' directly [-fpermissive]
用MSVC2013/2015编译成功,打印出
C (B *)
用clang 3.5编译成功并打印出
C
那么强制性的问题是哪一个是正确的? :)
(虽然我强烈倾向于 clang 版本,但 msvc 在更改类型后停止声明变量的方式从技术上讲它的 typedef 似乎有点奇怪)
最佳答案
GCC 是正确的,至少根据 C++11 查找规则。 3.4.3.1 [class.qual]/2 指定,如果嵌套名称说明符与类名相同,则它指的是构造函数而不是注入(inject)的类名。它给出了例子:
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
看起来 MSVC 将其误解为函数式转换表达式,创建了一个临时的 C
,其中 y
作为构造函数参数;并且 Clang 将其误解为对类型为 C
的名为 y
的变量的声明。
关于c++ - 程序在 3 个主要 C++ 编译器中以不同方式编译。哪一个是对的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29681449/