Reputation: 1616
I was looking into most vexing parse, and I stumbled upon something like this:
Foo bar(Baz()); // bar is a function that takes a pointer to a function that returns a Baz and returns a Foo
This is quite different from the typical syntax of return-type(*name)(parameters)
. Are the parenthesis present the parenthesis for the parameter list, or are they for the name?
Upvotes: 15
Views: 1394
Reputation: 238351
There are two sets of parentheses in the declaration. The outer set of parentheses are the parameter list of the function bar
:
Foo bar(Baz());
^ ^
Baz()
in this declaration is a function type. The parentheses in a function type declaration delimit the parameter list of that function.
Foo bar(Baz());
^^
To clarify: In the context of a function parameter declarator, a function type is adjusted to be a pointer to a function of that type. So the declaration is in fact equivalent to:
Foo bar(Baz(*)());
^ ^
The highlighted parentheses of this alternative pointer argument declarator are not present in the "pre-adjustement" declaration.
Relevant standard rule:
[dcl.fct]
The type of a function is determined using the following rules. The type of each parameter (including function parameter packs) is determined from its own decl-specifier-seq and declarator. After determining the type of each parameter, any parameter of type “array of T” or of function type T is adjusted to be “pointer to T”. ...
Upvotes: 6
Reputation: 17483
Are the parenthesis present the parenthesis for the parameter list, or are they for the name?
They are for the parameter list.
So:
Foo bar(Baz());
declares a function which accepts a single parameter of a type function which returns Baz
and accepts no parameters.
This, in turns, equal to a a function declaration which accepts a single parameter of a type pointer to a function which returns Baz
and accepts no parameters. as (from function):
The type of each function parameter in the parameter list is determined according to the following rules:
...
3) If the type is a function type F, it is replaced by the type "pointer to F"
...
Upvotes: 3
Reputation: 85767
Fully explicit form:
Foo bar(Baz f());
bar
is a function that takes a single parameter f
, which is a function (taking no arguments) returning Baz
.
Without naming the parameter:
Foo bar(Baz ());
The reason bar
ends up taking a pointer to a function is that functions cannot be passed by value, so declaring a parameter as a function automatically decays it into a pointer. The above declaration is equivalent to:
Foo bar(Baz (*)());
// or:
Foo bar(Baz (*f)()); // with a named parameter
This is similar to void foo(int [10])
where int [10]
also means int *
in a parameter list.
Upvotes: 18