Why "Foo f(Bar());" can be a declaration of a function that takes type Bar and returns type Foo? [duplicate]
I met this C++ question:
Question: Is the following a definition or a declaration?
Foo f(Bar());
Answer: It is possibly either a declaration of a function that takes type Bar and returns type Foo or it is a definition of f
as a type Foo
, which has a constructor that takes type Bar. The problem is the syntax for both is identical so to resolve this problem the C++ standard states that a compiler must prefer function declarations to object definitions where it is unable to make a distinction.
-- I don't understand why it can be "a declaration of a function that takes type Bar and returns type Foo"? how come a parenthesis "()" appear in parameter list?
The function f
actually takes a function pointer to a function that takes no arguments and gives a Bar
. The type of the argument to f
is Bar (*)()
.
This code fails to compile (and we can see the actual type of the argument in the error message):
class Foo { };
class Bar { };
Foo f(Bar());
int main() {
Bar b;
f(b);
return 0;
}
But this code does compile:
class Foo { };
class Bar { };
Foo f(Bar());
Bar g();
int main() {
f(g);
return 0;
}
The second meaning it could have, as you say in the question, is that you are making a new Foo
object called f
and you are calling the constructor with Bar()
(a new instance of Bar
). It would be similar to:
Foo f = Foo(Bar());
In this situation of Foo f(Bar());
though, the first interpretation is chosen by the compiler.
Somewhat confusingly, if you add another set of parentheses, as in
Foo f((Bar()));
the compiler picks the second interpretation.