【发布时间】:2015-06-23 06:09:58
【问题描述】:
作为我上一个问题的一个有趣的后续行动(尽管实际上并不重要): 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 似乎有点奇怪)
【问题讨论】:
-
C::C y;没有意义,对吧?C::C (y);也不是 起初我以为这是 Most-Vexing-Parse stackoverflow.com/questions/tagged/most-vexing-parse 的一个实例,但现在我认为这只是未定义的行为,这意味着所有三个编译器都是“正确的”。 -
#3 clang 肯定是错的,#2 msvc 太宽松了,#1 g++ 是对的((我猜)
-
C::C没有命名类型,而是命名了函数,因此 GCC 是正确的 imo。
标签: c++ language-lawyer