Search code examples
c++structconstructordefault-constructormost-vexing-parse

Unclear most vexing parse


Let's assume the following class Foo.

struct Foo
{
  int i;
};

if I want to make an instance of this class and initialize it, I should do: Foo foo1 = Foo(); to call the constructor.

int main(void)
{
    foo1 = Foo(); 
    cout << foo1.i << " : " << foo1.j << endl; // " 0 " 
}

then I thought I'd call the default constructor with the following line but it doesn't:

int main(void)
{
    Foo foo2(); // most vexing parse
    cout << foo2  << endl; // " 1 " ??? why?
    foo2.i++; // error: request for member ‘i’ in ‘foo2’, which is of non-class type ‘Foo()’ 
}

Why is foo2 initialized to int(1) and not Foo()?

I know about the most vexing parse, it tells that, from my understanding, when a line can be interpreted as a function, it is interpreted as a function.

But foo1() is interpreted as an int, not a function, nor a Foo class.

The line Foo foo2() compiles because it is interpreted as a function prototype. OK.

Why does this line compiles? cout << foo2 << endl;

Does it print the address of the foo2 function?


Solution

  • As you said, Foo foo2(); is a function declaration. For cout << foo2, foo2 would decay to function pointer, and then converts to bool implicitly. As a non-null function pointer, the converted result is true.

    Without using boolalpha, the std::basic_ostream<CharT,Traits>::operator<< would output 1 for true.

    If boolalpha == 0, then converts v to type int and performs integer output.

    You can see it more clearer with usage of std::boolalpha.

    cout << boolalpha << foo2  << endl;  // print out "true"