我相信如下这个问题,写过C++的人或许都曾经遇到过。
Why does the compiler interpret this line as a function definition and not as a variable definition?
Y y(X());
in the following code:
#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 gives the following error on line "y.f();"
leftof '.f'must have class/struct/union
Consider this :
This declares a function foo
( accepting a function returning int
) returning float
.
Now read
Y y(X());
as y
as function (accepting a function returning X
)returning Y
The problem arises due to C++ most vexing parse
Can besolved with :
Y y{ X() }; // requires C++11
or
Y y( ( X() ) );
// ^ ^ notice parenthesis
A quote from the standard :
§ 8.2 Ambiguity resolution[dcl.ambig.res]
1 - The ambiguity arising from the similarity between afunction-style cast and a declaration mentioned in 6.8 can also occur in thecontext of a declaration. In that context, the choice isbetween a function declaration with a redundant set of parentheses around aparameter name and an object declaration with a function-style cast as theinitializer. Just as for the ambiguities mentioned in6.8, there solution is to consider any construct that could possibly be a declaration adeclaration.[Note: a declaration can be explicitlydisambiguated by a nonfunction-style cast, by a = to indicate initialization orby removing the redundant parentheses around the parameter name. ]
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
}
Variable definition or function declaration?
int a(1); // variabledefinition
int b(); // function declaration
int b(foo); // variable definition or function declaration?
It is hard to distinguish variable definition with function declaration?It is called "most vexingparse" in C++, which is classicallydemonstrated with a line such as
Aa(B()); //declares a function
While this, for most, intuitively appears to be the declaration ofan object a of type A, taking a temporary B object as aconstructor parameter, it's actually a declaration of a function a returning an A, taking a pointer to afunction which returns B and itself takes no parameters. Similarlythe line
Aa(); //declares a function
also falls under the same category, since instead of an object, it declares a function. Now, in the first case, the usual workaround for thisissue is to add an extra set of brackets/parenthesis around the B(), as the compiler will then interpret it as the declaration of anobject
Aa((B())); //declares an object
However, in the secondcase, doing the same leads to a compile error
Aa(()); //compile error
If you do have anexpression within then it is valid. For example:
A a((0));//compiles
The final solution tothis issue is to move to the C+11 uniform initialization syntax if you can.
Aa{};
Ref:
http://stackoverflow.com/questions/1424510/most-vexing-parse-why-doesnt-a-a-work
http://stackoverflow.com/questions/26399686/function-definition-or-variable-definition
http://www.stroustrup.com/C++11FAQ.html#uniform-init