我一直在研究大多数令人烦恼的解析,但偶然发现了这样的东西:
Foo bar(Baz()); // bar is a function that takes a pointer to a function that returns a Baz and returns a Foo
这与return-type(*name)(parameters)
的典型语法有很大不同。括号是在参数列表的括号中显示还是在名称中?
答案 0 :(得分:16)
完全明确的形式:
Foo bar(Baz f());
bar
是一个带有单个参数f
的函数,它是一个返回Baz
的函数(不带参数)。
不命名参数:
Foo bar(Baz ());
bar
最终使用指向函数的指针的原因是,函数无法按值传递,因此将参数声明为函数会自动将其衰减为指针。上面的声明等同于:
Foo bar(Baz (*)());
// or:
Foo bar(Baz (*f)()); // with a named parameter
这类似于void foo(int [10])
,其中int [10]
在参数列表中也表示int *
。
答案 1 :(得分:5)
声明中有两组括号。括号的外部是函数bar
的参数列表:
Foo bar(Baz());
^ ^
此声明中的 Baz()
是一种函数类型。函数类型声明中的括号定界了该函数的参数列表。
Foo bar(Baz());
^^
要澄清:在函数参数声明符的上下文中,调整了一个函数类型以使其成为该类型函数的指针。因此,声明实际上等于:
Foo bar(Baz(*)());
^ ^
“未调整的”声明中不存在此替代指针参数声明符的突出显示的括号。
相关标准规则:
[dcl.fct]
使用以下规则确定函数的类型。 每个参数(包括功能参数包)的类型由其自己的decl-specifier-seq和声明符确定。 在确定每个参数的类型之后,将类型为“ T的数组”或功能类型为T的任何参数调整为“指向T的指针”。 ...
答案 2 :(得分:2)
括号是在参数列表的括号中显示还是名称??
它们用于参数列表。
所以:
Foo bar(Baz());
声明一个函数,该函数接受类型为 function的单个参数,该函数返回Baz
并且不接受任何参数。
这反过来等于一个函数声明,该函数声明接受类型为的单个参数,该指针指向返回Baz
并且不接受任何参数的函数。如(来自{{3 }}):
参数列表中每个功能参数的类型根据以下规则确定:
...
3)如果类型是函数类型F,则将其替换为“指向F的指针”类型
...