Where in the standard are functions returning functions disallowed? I understand they are conceptually ridiculous, but it seems to me that the grammar would allow them. According to this webpage, a "noptr-declarator [is] any valid declarator" which would include the declarator of a function:
int f()();
Regarding the syntax.
It seems to me that the syntax, as spelled out in [dcl.decl], allows
int f(char)(double)
which could be interpreted as the function f
that takes a char
and returns a function with same signature as int g(double)
.
1 declarator:
2 ptr-declarator
3 noptr-declarator parameters-and-qualifiers trailing-return-type
4 ptr-declarator:
5 noptr-declarator
6 ptr-operator ptr-declarator
7 noptr-declarator:
8 declarator-id attribute-specifier-seq opt
9 noptr-declarator parameters-and-qualifiers
10 noptr-declarator [ constant-expression opt ] attribute-specifier-seq opt
11 ( ptr-declarator )
12 parameters-and-qualifiers:
13 ( parameter-declaration-clause ) cv-qualifier-seqAfter
Roughly speaking, after 1->2, 2=4, 4->6, 4->6 you should have ptr-operator ptr-operator ptr-operator Then, use 4->5, 5=7, 7->8 for the first declarator; use 4->5, 5=7, 7->9 for the second and third declarators.
From [dcl.fct], pretty explicitly:
Functions shall not have a return type of type array or function, although they may have a return type of type pointer or reference to such things. There shall be no arrays of functions, although there can be arrays of pointers to functions.
With C++11, you probably just want:
std::function<int()> f();
std::function<int(double)> f(char);
There is some confusion regarding the C++ grammar. The statement int f(char)(double);
can be parsed according to the grammar. Here is a parse tree:
Furthermore such a parse is even meaningful based on [dcl.fct]/1:
In a declaration
T D
whereD
has the form
D1
( parameter-declaration-clause ) cv-qualifier-seqopt
ref-qualifieropt exception-specificationopt attribute-specifier-seqoptand the type of the contained declarator-id in the declaration
T D1
is “derived-declarator-type-listT
”, the type of the declarator-id inD
is “derived-declarator-type-list function of (parameter-declaration-clause ) cv-qualifier-seqopt ref-qualifieropt returningT
”.
In this example T == int
, D == f(char)(double)
, D1 == f(char)
. The type of the declarator-id in T D1
(int f(char)
) is "function of (char) returning int". So derived-declarator-type-list is "function of (char) returning". Thus, the type of f
would be read as "function of (char) returning function of (double) returning int."
It's ultimately much ado about nothing, as this is an explicitly disallowed declarator form. But not by the grammar.