问题
From § 8.3.5.11 of ISO/IEC 14882:2011(E):
A typedef of function type may be used to declare a function but shall not be used to define a function
The standard goes on to give this example:
typedef void F();
F fv; // OK: equivalent to void fv();
F fv { } // ill-formed
void fv() { } // OK: definition of fv
What motivates this rule? It seems to limit the potential expressive usefulness of function typedefs.
回答1:
Though this question is about C++, but since C++ inherits typedef
and function pointer from C, so an explanation of the same question in C can be used in here. There's a formal explanation for C.
Rationale for International Standard - Programming Languages C §6.9.1 Function definitions
An argument list must be explicitly present in the declarator; it cannot be inherited from a
typedef
(see §6.7.5.3). That is to say, given the definition:typedef int p(int q, int r);
the following fragment is invalid:
p funk // weird { return q + r ; }
Some current implementations rewrite the type of, for instance, a
char
parameter as if it were declaredint
, since the argument is known to be passed as anint
in the absence of a prototype. The Standard requires, however, that the received argument be converted as if by assignment upon function entry. Type rewriting is thus no longer permissible.
回答2:
It's probably mostly historical reasons. typedef
was a relatively late addition to C, and was tacked onto the existing language (and caused a few problems for the parsing phase of compilers).
Also, a function definition has to define the names of the parameters, if any. A function type includes the function's return type and parameter types, but not its parameter names. For example, these:
void (int)
void (int x)
void (int y)
are three ways of writing the same function type. If you had:
typedef void func_t(int);
then this hypothetical definition:
func_t some_func { }
wouldn't define a name for its int
parameter. I'm not sure how that could have been resolved in a reasonable manner. It would be possible, I suppose, but it was never done.
But the bottom line is probably just that Dennis Ritchie either didn't think it was worth the effort to define how a typedef
could be used in a function definition, or he simply didn't think of it.
回答3:
Let me put a few words. Consider a statement:
typedef void F(int p1, char* p2);
This statement assigns name F
to a function signature void (int, char*);
This is definition of an alias to the function signature. After that the statement:
F fv;
tells that there is a function fv
. It has the signature that was mentioned above and it has its body somewhere. Look at the C/C++ syntax of the function definition:
retType funcName(params) { body }
There are actually 2 names used retType
and funcName
. None of them are the same to the name F
from the initial typedef. The name F
has meaning of both names. If language would allow something like:
F { body }
this will associate body with the function type. But this leads a problem:
The meaning of F
would be not clear. Is it an "alias to the function signature" or is it a "name of the entry point into a code"?
Plus the syntax of the last example would be weird to millions of C/C++ programmers.
回答4:
The rule is as you quoted - typedef of function type shall not be used to define a function
. In the 3rd line of the example, you are trying to define a function with function type F
. This is not allowed by the standard.
EDIT
As you pointed out, I try to explain more on it.
For the 3rd line, if it were legal, then you could replace F with the typedef definition:void fv { }()
. This is not a legal definition or declaration in C++.
I think the key point is that typedef
is just creating an alias for simplification, and you can replace your typedef type like replacement of #define
during compilation.
来源:https://stackoverflow.com/questions/17848983/why-cant-a-typedef-of-a-function-be-used-to-define-a-function