函数定义还是变量定义?

Lau*_*tei 5 c++ most-vexing-parse language-lawyer

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

Y y(X());
Run Code Online (Sandbox Code Playgroud)

在以下代码中:

#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();
}
Run Code Online (Sandbox Code Playgroud)

VS2010在"yf();"行上给出以下错误:

left of '.f' must have class/struct/union
Run Code Online (Sandbox Code Playgroud)

标准的哪一部分描述了这种行为?以下问题的答案并未提供有关它的详细信息: 最令人烦恼的解析

P0W*_*P0W 6

考虑一下:

float foo( int () )

这声明了一个函数foo(接受函数返回int)返回float.

现在看了

Y y(X());
Run Code Online (Sandbox Code Playgroud)

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

问题出现是由于C++最令人烦恼的解析

可以解决:

 Y y{ X() }; // requires C++11
Run Code Online (Sandbox Code Playgroud)

要么

Y y( ( X() ) );
  // ^     ^ notice parenthesis 
Run Code Online (Sandbox Code Playgroud)

基于编辑更新:

一个从标准的报价:

§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]
Run Code Online (Sandbox Code Playgroud)

类似地,此后的其他示例.

  • `Y y = X();`不等于`Y y {X()};`.C++ 03中的正确解决方案是`Y y((X()));` (2认同)

For*_*veR 5

最令人烦恼的解析问题。Y y(X())实际上是带有 name 的函数声明y,它返回Y并接收函数类型的参数,但不返回X和接收任何内容。

它在 C++11 中通过使用{}for 构造对象来解决。