C++ 为什么可以';函数的typedef不能用于定义函数吗?

C++ 为什么可以';函数的typedef不能用于定义函数吗?,c++,typedef,function-declaration,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 这条规则的动机是什么?这似乎限制了函数类型定义的潜在表达有用性。规则如您所引用-函数类型的类型定义不得用于定

根据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

这条规则的动机是什么?这似乎限制了函数类型定义的潜在表达有用性。

规则如您所引用-
函数类型的类型定义不得用于定义函数。在示例的第3行中,您试图定义一个函数类型为
F
。这是标准不允许的


编辑
正如你所指出的,我试着对此作更多解释

对于第三行,如果它是合法的,那么您可以用typedef定义替换F:
void fv{}()
。这不是C++中的法律定义或声明。
我认为关键的一点是,
typedef
只是为了简化而创建了一个别名,您可以在编译过程中替换typedef类型,就像替换
#define
一样。

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

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

void (int)
void (int x)
void (int y)
有三种编写相同函数类型的方法。如果你有:

typedef void func_t(int);
那么这个假设的定义是:

func_t some_func { }
typedef int p(int q, int r);
retType  funcName(params) { body }
不会为其
int
参数定义名称。我不确定如何以合理的方式解决这一问题。我想这是可能的,但从来没有实现过


<>但是,Dennis Ritchie的根本原因也许是不认为定义函数<定义> TyPufF是值得的,或者他根本没有想到。< /P> < P>虽然这个问题是关于C++的,但是因为C++继承了<代码> TyPufF和C的函数指针,因此,这里可以使用C语言对同一问题的解释。对C有一个正式的解释

§6.9.1功能定义 参数列表必须显式出现在声明器中;它不能从类型定义继承(见§6.7.5.3)。也就是说,根据定义:

func_t some_func { }
typedef int p(int q, int r);
retType  funcName(params) { body }
以下片段无效:

p funk // weird
{ return q + r ; }
当前的一些实现重写了
char
参数的类型,就好像它被声明为
int
,因为在没有原型的情况下,参数被称为
int
。然而,该标准要求接收到的参数被转换,就像在函数输入时通过赋值一样。因此,不再允许类型重写


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

typedef void F(int p1, char* p2);
F fv;
此语句将name
F
赋值给函数签名
void(int,char*)这是函数签名别名的定义。在此之后,声明:

typedef void F(int p1, char* p2);
F fv;
表示有一个函数
fv
。它有上面提到的签名,它的身体在某处。查看函数定义的C/C++语法:

func_t some_func { }
typedef int p(int q, int r);
retType  funcName(params) { body }
实际上使用了两个名称
retType
funcName
。它们都与初始typedef中的名称
F
不相同。名称
F
具有两个名称的含义。如果语言允许以下内容:

F { body }
这将使主体与函数类型相关联。但这带来了一个问题:

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


再加上上上一个例子的语法对数百万C/C++程序员来说是很奇怪的。

想想看:
typedef
为另一个类型创建了一个别名,在您的例子中,它是一个函数类型。在第三个(格式错误)示例中,
F
是指函数的返回类型还是函数本身的类型?@MarkGarcia:它是函数本身的类型,因为没有括号分隔参数。换言之,如果语言允许,它可以得到明确的解决;基思·汤普森说,这句话给了我一些想法。那么,函数参数呢?如果以这种方式定义函数,您将如何引用函数参数?@MarkGarcia:Yup;看到我的答案了。但这条规则的动机是什么?我想他知道这条规则是引用的。他引用了它,并给出了章节和诗句。@MartinDrozdik为第三行,如果它是合法的,那么你可以用typedef定义替换F:void fv{}()。这不是C++@BenjaminLindley中的法律定义或声明,我重新编辑了我的帖子。你可以看看并指出任何建议。你只是告诉他标准是怎么说的。他已经知道了。他在问题中引用了这句话。他在问为什么标准规则是这样写的。我没有任何建议,因为我不知道这个规则的原因。但是有一些无名的参数,只是不能引用它们是完全可以的。因此,您的假设将与编写
void some_func(int){}
@BenjaminLindley相同:是的,但这意味着通过
typedef
定义的函数不能有命名参数。这将是一个恼人和武断的限制。允许一个特殊情况而不能概括它是不值得的。C,其中Type DEFS起源,不允许函数定义中的无名参数。不知道C。我想看到C++标准的类似的原理文档。有吗?(到目前为止,我读过的最好的方法是斯特劳斯塔普的书…@gx_uu)据我所知不是这样。我也很想看看。