5

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

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 在“yf();”行给出以下错误

left of '.f' must have class/struct/union

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

4

2 回答 2

6

考虑一下:

float foo( int () )

这声明了一个返回的函数foo(接受返回的函数intfloat

现在阅读

Y y(X());

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

问题的出现是由于C++ 最令人头疼的解析

可以解决:

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

或者

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

基于编辑更新:

标准的引述

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

1 - 由于函数样式转换和 6.8 中提到的声明之间的相似性而产生的歧义也可能出现在声明的上下文中。在这种情况下,选择是在参数名称周围带有一组冗余括号的函数声明和以函数样式强制转换作为初始值设定项的对象声明之间进行选择。正如6.8中提到的歧义一样,解决方案是将任何可能是声明的构造视为声明。[注意:声明可以通过非函数式强制转换、= 表示初始化或删除参数名称周围的冗余括号来明确消除歧义。]

[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]

类似的其他示例如下。

于 2014-10-16T08:37:58.453 回答
4

最令人头疼的解析问题Y y(X())实际上是带有 name 的函数声明y,它返回Y和接收函数类型的参数,它X什么也不返回和接收。

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

于 2014-10-16T08:36:47.747 回答