2

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?

Guillaume D
  • 2,202
  • 2
  • 10
  • 37
  • 2
    Use a debugger to find out which `operator<<` overload the compiler picked. – Ulrich Eckhardt Jul 22 '19 at 12:53
  • *if I want to make an instance of this class and initialize it, I should do: `Foo foo1 = Foo();` to call the constructor.* No, you should just do `Foo foo1;` or `Foo foo1 {};`, depending on what you want to do. – ruohola Jul 22 '19 at 12:56
  • 1
    Note that there is no "most vexing parse" here. The most vexing parse does involve the same rule about function declarations. Here is an example of the most vexing parse: `Foo foo2(int());` (rewrote my comment, since my original example wasn't quite complete) – eerorika Jul 22 '19 at 13:09

1 Answers1

6

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"
songyuanyao
  • 169,198
  • 16
  • 310
  • 405