C ++ 0x lambda for makecontext # 2 argument

I had a problem with passing a C ++ 0x lambda function as the second argument to makecontext(from ucontext.h). Signatures makecontext:

void makecontext(ucontext_t*, void (*)(), int, ...);

I used to be able to apply C-style casting (void (*)(void))to the global sphere functions that I used. A reinterpret_castwill do the trick in C ++. However, using the C ++ 0x lambda function, I get the following error:

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

I am using g ++ 4.6. To get a compilation error, the following code is enough:

#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;
}
+5
source share
3 answers

[](int i){} - , int ; void(*)(int): , int .

, makecontext ( , , , ), , lambda: , , , void(*)():

auto f2 = [](int i) { };
makecontext(&c, (void (*)(void))(void (*)(int))f2, 1, 123);

( - ), . makecontext , , , .

+6

, f2, , makecontext. , , std::bind ( < > ) , void(*)(void):

auto f3 = std::bind(f2, 0);
makecontext(&c, f3, 1, 123);

f3 - , - . , f2 0 . f2, bind.

, , makecontext . , , , , ( ): , . , , .

+1

You can use the wrapper function to wrap it. It works for every lambda. The idea is that since you cannot pass a functor as a function pointer, you can pass a wrapper function that calls the lambda function. Another trick is that I need to pass a pointer instead of the whole object, because makecontext can only accept int arguments.

template<typename Kernel, typename ...Args>
void wrapper(Kernel *ker, Args*... args)
{
    (*ker)(*args...);
}
template<typename Ker, typename ...Args>
void makectx(Ker ker, Args... args)
{
    makecontext(&ctx, (void (*)(void))wrapper<Ker, Args...>, sizeof...(Args) + 1, &ker, &args...);
}
0
source

All Articles