我无法将 C++0x lambda 函数作为第二个参数传递给 makecontext
(来自 ucontext.h)。 makecontext
的签名是:
void makecontext(ucontext_t*, void (*)(), int, ...);
以前,我能够将 C 风格的 (void (*)(void))
转换应用于我使用的全局范围函数。 reinterpret_cast
可以在 C++ 中实现这一目的。但是,使用 C++0x lambda 函数时,出现以下错误:
error: invalid cast from type ‘main(int, char**)::<lambda(int)>’ to type ‘void (*)()’
我正在使用 G++ 4.6。以下代码足以产生编译错误:
#include <ucontext.h>
void f1(int i) {}
int main(int argc, char *argv[]) {
ucontext_t c;
makecontext(&c, (void (*)(void))f1, 1, 123); // ok
makecontext(&c, reinterpret_cast<void (*)(void)>(f1), 1, 123); // ok
auto f2 = [](int i){};
makecontext(&c, (void (*)(void))f2, 1, 123); // error
makecontext(&c, reinterpret_cast<void (*) (void)>(f2), 1, 123); // error
return 0;
}
最佳答案
[](int i){}
是一个无捕获的 lambda,它只有一个 int
参数并且不返回任何内容;因此,它可以隐式转换为 void(*)(int)
:指向接受单个 int
且不返回任何内容的函数的指针。
假设 makecontext
函数能够处理不同类型的函数(从它的文档中可以看出,尽管文档有点含糊),那么您将需要使用两个转换将它与 lambda 一起使用:一种是将 lambda 转换为函数指针,另一种是将 lambda 转换为 void(*)()
类型:
auto f2 = [](int i) { };
makecontext(&c, (void (*)(void))(void (*)(int))f2, 1, 123);
这非常不安全(在函数指针类型之间进行转换并不是最安全的做法),因此最好将此类功能包装到实用程序库中。您可以使用函数模板包装 makecontext
函数,这样您就可以确保对该函数的所有使用都是类型安全的,并且所有不安全的代码都封装在一个地方。
关于Makecontext 参数 #2 的 C++0x lambda,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6809890/