作为我上一个问题的一个有趣的后续(虽然没有很大的实际意义):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进行
-fpermissive
C (B *)
C所以必须问的问题是哪一个是正确的?:)
(我强烈倾向于clang版本和msvc的方式来停止声明变量,只是在技术上改变了它的typedef的类型,这看起来有点奇怪)
发布于 2015-04-17 01:17:35
至少根据C++11查找规则,GCC是正确的。3.4.3.1 class.qual/2指定,如果嵌套名称说明符与类名相同,它引用的是构造函数,而不是注入的类名。它给出了示例:
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错误地将其解释为函数样式的强制转换表达式,创建了一个以y作为构造函数参数的临时C;而Clang错误地将其解释为C类型的名为y的变量的声明。
发布于 2015-04-17 01:14:37
G++是正确的,因为它给出了错误。因为构造函数不能在没有new运算符的情况下以这种格式直接调用。尽管您的代码调用了C::C,但它看起来像是一个构造函数调用。但是,根据C++11标准3.4.3.1,这不是合法的函数调用,也不是类型名(see Mike Seymour's answer)。
Clang是错误的,因为它甚至没有调用正确的函数。
MSVC是合理的,但它仍然不遵循标准。
https://stackoverflow.com/questions/29681449
复制相似问题