Makecontext 参数 #2 的 C++0x lambda

标签 c++ c++11 lambda

我无法将 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/

相关文章:

c++ netbeans 显示语法错误,但编译和运行正确

c++ - rdstate() 返回值是什么意思?

ruby - RSpec -- lambda 用法

c++ - 混合 C++ ABI 以针对遗留库进行构建

c++ - 编译器似乎更改了我的 const 参数

c++ - 如何根据 OpenGL 规范安全地确保(在任何平台上)正确实现 char* 类型?

c++ - 如何在 C 中公开 C++ 函数指针?

c++ - 我如何根据宏中的类型做出决定?

amazon-web-services - 在 AWS LAMBDA x 小时后创建自动终止的 EC2 实例

c# - 使用 lambda 表达式将对象列表从一种类型转换为另一种类型