NeonGlow NeonGlow - 3 months ago 21
C++ Question

Most vexing parse

I saw a code here at Cpp Quiz [Question #38]

#include <iostream>

struct Foo
{
Foo(int d) : x(d) {}
int x;
};

int main()
{
double x = 3.14;

Foo f( int(x) );

std::cout << f.x << std::endl;

return 0;
}


It is said there that this code is ill formed because
Foo f( int(x) );
will be treated as a function declaration rather than an object declaration of type
Foo
. As far as I know, this is an instance of most vexing parse. My question is what is this syntax int(x) in statement
Foo f( int(x) );
means? So far I only saw function declarations like:


  1. Foo f( int );
    and

  2. Foo f( int x );



Is it same as
Foo f( int x );
?

Answer

what is this syntax int(x) in statement Foo f( int(x) ); means?

The parentheses around x are superfluous and will be ignored. So int(x) is same as int x here, means a parameter named x with type int.

Is it same as Foo f( int x );?

Yes. Foo f( int(x) );, is a function declaration which is named f, returns Foo, takes one parameter named x with type int.

Here's the explanation from the standard. $8.2/1 Ambiguity resolution [dcl.ambig.res]:

(emphasis mine)

The ambiguity arising from the similarity between a function-style cast and a declaration mentioned in [stmt.ambig] can also occur in the context of a declaration. In that context, the choice is between a function declaration with a redundant set of parentheses around a parameter name and an object declaration with a function-style cast as the initializer. Just as for the ambiguities mentioned in [stmt.ambig], the resolution is to consider any construct that could possibly be a declaration a declaration. [ Note: A declaration can be explicitly disambiguated by adding parentheses around the argument. The ambiguity can be avoided by use of copy-initialization or list-initialization syntax, or by use of a non-function-style cast. — end note ] [ 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 y((int)a);      // object declaration
  S z = int(a);     // object declaration
}

— end example ]

So, int(x) will be considered as a declaration (of parameter) rather than a function style cast.