今天我遇到了this段代码:
int main() {
struct Foo {};
struct Bar {};
Foo(b)(int (Bar*c)); // ?
return 0;
}
我完全不知道发生了什么。我的编译器(VC14)警告我未使用的原型函数?
这行做什么(声明一个函数:哪个名称,什么参数和返回类型?如何调用它?)
Foo(b)(int (Bar*c));
提前感谢您帮助我!
答案 0 :(得分:6)
这声明了一个名为b
的函数:
int (Bar*c)
为参数; Foo
。参数的类型int (Bar*c)
是指向函数的指针,该函数将指针指向Bar
并返回int
。这里,c
是参数的名称,可以省略:int (Bar*)
。
您可以通过以下方式致电b
:
int main() {
struct Foo {};
struct Bar {};
Foo(b)(int (Bar* c)); // the prototype in question
int func(Bar*); // a function defined elsewhere
Foo result = b(func);
return 0;
}
答案 1 :(得分:4)
这不是有效的C(因为名称Foo
和Bar
没有引用类型;您必须使用struct
关键字或使用typedef。
在C ++中,这是一个令人惊讶但有效的声明。它将b声明为一个返回Foo的函数,并采用类型为“(指向)函数的参数返回int,将类型指针的参数转换为Bar”。
为了生成可读类型声明,我编写了以下代码:
#include <typeinfo>
#include <iostream>
int main() {
struct Foo {};
struct Bar {};
Foo(b)(int (Bar*c));
std::cout << typeid(b).name();
return 0;
}
然后我编译了它并通过c++filt
过滤了它的输出。
结果是:
main::Foo (int (*)(main::Bar*))
完全清楚。
答案 2 :(得分:2)
实际上,我的编译器(Clang 3.5)给了我以下警告:
警告:括号被消除歧义为函数声明 [-Wvexing-解析]
当你正在处理Most vexing parse时,更重要的是。
以下声明:
Foo(b)(int (Bar*c));
声明b
函数指针指向返回Foo
的函数,并将返回int
的函数作为参数,并将指针指向{{ 1}}一个参数(例如:Bar
)。
您的编译器可能认为这是函数的原型,因此警告。