来自 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 的潜在表达用途。
来自 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 的潜在表达用途。
虽然这个问题是关于 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
但是,该标准要求将接收到的参数转换为好像通过函数输入时的赋值一样。因此不再允许类型重写。
这可能主要是历史原因。typedef
是对 C 的一个相对较晚的添加,并被添加到现有语言中(并在编译器的解析阶段引起了一些问题)。
此外,函数定义必须定义参数的名称(如果有)。函数类型包括函数的返回类型和参数类型,但不包括其参数名称。例如,这些:
void (int)
void (int x)
void (int y)
是编写相同函数类型的三种方式。如果你有:
typedef void func_t(int);
那么这个假设的定义:
func_t some_func { }
不会为其int
参数定义名称。我不确定如何以合理的方式解决这个问题。我想这是可能的,但它从未完成。
但底线可能只是 Dennis Ritchie 要么认为定义如何typedef
在函数定义中使用 a 是不值得的,要么他根本没有想到这一点。
让我说几句。考虑一个声明:
typedef void F(int p1, char* p2);
此语句将名称分配F
给函数签名void (int, char*);
这是函数签名别名的定义。之后的声明:
F fv;
告诉有一个函数fv
。它具有上面提到的签名,并且在某处有它的主体。查看函数定义的 C/C++ 语法:
retType funcName(params) { body }
实际上使用了 2 个名称retType
和funcName
. 它们都不与F
初始 typedef 中的名称相同。该名称F
具有两个名称的含义。如果语言允许类似:
F { body }
这会将主体与函数类型相关联。但这会导致一个问题:
的含义F
将不清楚。它是“函数签名的别名”还是“代码入口点的名称”?
另外,上一个示例的语法对于数百万 C/C++ 程序员来说会很奇怪。
规则如您所引用 - 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。