为什么不能使用函数的typedef来定义函数?

时间:2013-07-25 04:25:58

标签: c++ typedef function-declaration

来自ISO / IEC 14882:2011(E)的§8.3.5.11:

  

函数类型的typedef可用于声明函数但不得用于定义函数

标准继续给出这个例子:

typedef void F();
F fv; // OK: equivalent to void fv();
F fv { } // ill-formed
void fv() { } // OK: definition of fv

这条规则的动机是什么?它似乎限制了函数typedef的潜在表达用途。

4 个答案:

答案 0 :(得分:12)

虽然这个问题是关于C ++的,但由于C ++从C继承了typedef和函数指针,因此可以在这里使用C中相同问题的解释。对C有一个正式的解释。

  

Rationale for International Standard - Programming Languages C§6.9.1函数定义

     

参数列表必须显式出现在声明符中;它不能从typedef继承(参见§6.7.5.3)。也就是说,给定定义:

typedef int p(int q, int r);
     

以下片段无效:

p funk // weird
{ return q + r ; }
     

某些当前实现重写了一个char参数的类型,就像它被声明为int一样,因为已知该参数在缺席时作为int传递一个原型。但是,标准要求将收到的参数转换为就像在函数输入时的赋值一样。因此不再允许类型重写。

答案 1 :(得分:7)

这可能主要是历史原因。 typedef是C的相对较晚的补充,并且被添加到现有语言中(并且在编译器的解析阶段引起了一些问题)。

此外,函数定义必须定义参数的名称(如果有)。函数类型包括函数的返回类型和参数类型,但不包括其参数名称。例如,这些:

void (int)
void (int x)
void (int y)

是编写相同函数类型的三种方法。如果你有:

typedef void func_t(int);

那么这个假设的定义:

func_t some_func { }

不会为其int参数定义名称。我不确定如何以合理的方式解决这个问题。我想,这是可能的,但它从未完成。

但最重要的可能就是Dennis Ritchie要么不认为定义如何在函数定义中使用typedef,或者他根本没有想到它。

答案 2 :(得分:1)

让我说几句话。考虑一个声明:

typedef void F(int p1, char* p2);

此语句将名称F分配给函数签名void (int, char*);这是函数签名的别名的定义。在那之后声明:

F fv;

告诉我有一个函数fv。它有上面提到的签名,它的身体在某处。查看函数定义的C / C ++语法:

retType  funcName(params) { body }

实际上有2个名称使用retTypefuncName。它们都与初始typedef中的名称F无关。名称F具有两个名称的含义。如果语言允许这样的话:

F { body }

这会将body与函数类型相关联。但这导致了一个问题:

F的含义不明确。它是“函数签名的别名”还是“代码入口点的名称”?

另外,最后一个例子的语法对数百万C / C ++程序员来说很奇怪。

答案 3 :(得分:-4)

规则与您引用的一样 - typedef of function type shall not be used to define a function。在示例的第3行中,您尝试定义函数类型为F的函数。标准不允许这样做。


修改
正如你所指出的那样,我试着解释一下它。

对于第3行,如果它是合法的,那么你可以用typedef定义替换F:
void fv { }()。这不是C ++中的合法定义或声明。

我认为关键点是typedef只是为简化创建了一个别名,你可以在编译期间替换你的typedef类型,如替换#define