The first one declares a function called f
that takes no parameters and returns g
.
g( f() );
// ^ ^ redundant set of parentheses
The second one is the same, with yet another redundant set of parentheses (remember that you can have as many declarations of the same functions as you wish). They are not always useless, though. You need them, say, to declare a function that returns a function pointer:
// function taking an int and returning
// a pointer to a function that takes a char
// and returns a g
g ( *f(int) )(char);
//^ ^ needed, syntax error without them
As for third:
When #1 and #2 are there, you've got a function declaration for f
in main
and g myG( ( f() ) );
is parsed as a declaration of an object of type g
, named myG
and initialized with a result of a function call. You get a linker error because there's no definition for f
.
When #1 and #2 are commented out, the type f
is visible, and the disambiguation with parentheses kicks in:
g myG( ( f() ) )
// ^ ^ these force an expression
Without that pair, you'd get another function declaration.
What you want is this:
( g(f()) );
// ^ ^ must be an expression as declarations can't be parenthesized
or something less Lisp-y: static_cast<g>(f());