函数定义还是变量定义?

时间:2014-10-16 08:33:10

标签: c++ language-lawyer most-vexing-parse

为什么编译器将此行解释为函数定义而不是变量定义:

Y y(X());

在以下代码中:

#include <iostream>

struct X {
  X() { std::cout << "X"; }
};

struct Y {
  Y(const X &x) { std::cout << "Y"; }
  void f() { std::cout << "f"; }
};

int main() {
  Y y(X());
  y.f();
}

VS2010在行&#34; y.f();&#34;

上给出以下错误
left of '.f' must have class/struct/union

标准的哪一部分描述了这种行为? 以下问题的答案并没有提供有关它的详细信息: Most vexing parse

2 个答案:

答案 0 :(得分:6)

考虑一下:

float foo( int () )

这声明函数foo(接受返回int的函数)返回float

现在阅读

Y y(X());

作为y作为函数(接受返回X的函数)返回Y

问题出现在C++ most vexing parse

之后

可以通过以下方式解决:

 Y y{ X() }; // requires C++11

Y y( ( X() ) );
  // ^     ^ notice parenthesis 

更新基于编辑:

来自标准引用:

  

§ 8.2歧义解决[dcl.ambig.res]

     

1 - 函数式转换与6.8中提到的声明之间的相似性引起的歧义也可能出现在声明的上下文中。 在该上下文中,选择是在参数名称周围的冗余括号集的函数声明和具有函数样式转换作为初始化程序的对象声明之间。正如6.8中提到的含糊不清一样,解决方案是考虑任何可能是声明声明的构造。 [注意:声明可以通过非函数式转换明确消除歧义, a =表示初始化或删除参数名称周围的冗余括号。 ]

[Example:

struct S {
    S(int);
};

void foo(double a)
{
   S w(int(a));  // function declaration
   S x(int());   // function declaration
   S y((int)a);  // object declaration
   S z = int(a); // object declaration
}
—end example]

与此相似的其他例子。

答案 1 :(得分:4)

Most vexing parse problemY y(X())实际上是名为y的函数声明,它返回Y并接收类型为function的参数,返回X并且什么也没有收到。

在C ++ 11中使用{}来构造对象。