C++ 0x lambda用于makecontext参数#2

use*_*370 5 c++ lambda c++11

我无法将C++ 0x lambda函数作为第二个参数传递给makecontext(来自ucontext.h).签名makecontext是:

void makecontext(ucontext_t*, void (*)(), int, ...);
Run Code Online (Sandbox Code Playgroud)

以前,我能够将C风格的(void (*)(void))强制转换应用到我使用的全局范围函数中.A reinterpret_cast可以用C++来解决问题.但是,使用C++ 0x lambda函数,我收到以下错误:

error: invalid cast from type ‘main(int, char**)::<lambda(int)>’ to type ‘void (*)()’
Run Code Online (Sandbox Code Playgroud)

我正在使用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;
}
Run Code Online (Sandbox Code Playgroud)

Jam*_*lis 6

[](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);
Run Code Online (Sandbox Code Playgroud)

这一切都相当不安全(函数指针类型之间的转换并不是最安全的事情),因此最好将这种功能包装到实用程序库中.您可以makecontext使用函数模板包装函数,以便确保函数的所有使用都是类型安全的,并且所有不安全的代码都封装在一个地方.