我正在调查最令人烦恼的解析,我偶然发现了这样的事情:
Foo bar(Baz()); // bar is a function that takes a pointer to a function that returns a Baz and returns a Foo
Run Code Online (Sandbox Code Playgroud)
这与典型的语法完全不同return-type(*name)(parameters)
.括号是否为参数列表的括号,或者它们是否为名称?
mel*_*ene 16
完全明确的形式:
Foo bar(Baz f());
Run Code Online (Sandbox Code Playgroud)
bar
是一个函数,它接受一个参数f
,这是一个函数(不带参数)返回Baz
.
没有命名参数:
Foo bar(Baz ());
Run Code Online (Sandbox Code Playgroud)
bar
最后得到函数指针的原因是函数不能通过值传递,因此将参数声明为函数会自动将其衰减为指针.以上声明相当于:
Foo bar(Baz (*)());
// or:
Foo bar(Baz (*f)()); // with a named parameter
Run Code Online (Sandbox Code Playgroud)
这类似于void foo(int [10])
在那里int [10]
也意味着int *
在一个参数列表.
声明中有两组括号.外部括号集是函数的参数列表bar
:
Foo bar(Baz());
^ ^
Run Code Online (Sandbox Code Playgroud)
Baz()
在此声明中是一个函数类型.函数类型声明中的括号分隔该函数的参数列表.
Foo bar(Baz());
^^
Run Code Online (Sandbox Code Playgroud)
澄清:在函数参数声明符的上下文中,函数类型被调整为指向该类型函数的指针.所以声明实际上相当于:
Foo bar(Baz(*)());
^ ^
Run Code Online (Sandbox Code Playgroud)
此替代指针参数声明符的突出显示的括号不存在于"未调整"声明中.
相关标准规则:
[dcl.fct]
使用以下规则确定函数的类型.每个参数的类型(包括函数参数包)由其自己的decl-specifier-seq和声明符确定.在确定每个参数的类型之后,将"T数组"或函数类型T的任何参数调整为"指向T的指针"....