12

来自 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

4 回答 4

13

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

国际标准的基本原理 - 编程语言 C §6.9.1函数定义

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

typedef int p(int q, int r);

以下片段无效:

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

一些当前的实现重写了例如char参数的类型,就好像它被声明了一样,因为已知参数在没有原型的情况下int作为 an 传递。int但是,该标准要求将接收到的参数转换为好像通过函数输入时的赋值一样。因此不再允许类型重写。

于 2013-07-25T05:05:09.543 回答
7

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

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

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

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

typedef void func_t(int);

那么这个假设的定义:

func_t some_func { }

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

但底线可能只是 Dennis Ritchie 要么认为定义如何typedef在函数定义中使用 a 是不值得的,要么他根本没有想到这一点。

于 2013-07-25T04:45:46.593 回答
1

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

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

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

F fv;

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

retType  funcName(params) { body }

实际上使用了 2 个名称retTypefuncName. 它们都不与F初始 typedef 中的名称相同。该名称F具有两个名称的含义。如果语言允许类似:

F { body }

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

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

另外,上一个示例的语法对于数百万 C/C++ 程序员来说会很奇怪。

于 2013-07-25T08:20:27.277 回答
-4

规则如您所引用 - typedef of function type shall not be used to define a function。在示例的第 3 行中,您尝试使用 function type 定义一个函数F。这是标准不允许的。


编辑
正如您所指出的,我尝试对此进行更多解释。

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

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

于 2013-07-25T04:33:14.987 回答