Krystian S
Krystian S

Reputation: 1616

Syntax of an un-named function pointer in C++

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

Answers (3)

eerorika
eerorika

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

Edgar Rokjān
Edgar Rokjān

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

melpomene
melpomene

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

Related Questions