My previous question concluded that a distasteful “double cast” might be necessary to use the POSIX makecontext with a C++ lambda function (i.e. function object). Moving on, I’m now faced with a compilation error relating to the following minimal code:
#include <iostream>
#include <ucontext.h>
using namespace std;
template <typename T> void foo() {
ucontext_t c;
auto f = [=](int i){ cout << i << endl; };
makecontext(&c, (void (*) (void)) (void (*)(int)) f, 1, 12345);
}
int main(int argc, char *argv[]) {
foo<int>();
return 0;
}
The error is:
error: invalid cast from type ‘foo() [with T = int]::<lambda(int)>’ to type ‘void (*)(int)’
However, if I remove the unused (in this example) template argument from the foo function, so it becomes void foo();, and change the call to foo() the error disappears. Could someone tell me why? I’m using G++ 4.6.
Edit:
From the comments below, it seems the [=] in the code above causes the lambda to be a “capturing” lambda, regardless of the fact that it doesn’t actually capture anything. The [=] is not necessary in my code, alas replacing with [] in GCC 4.6 does not remove the error. I am installing GCC 4.6.1 now…
If you use
[=]to induce your lambda, you will not get a function pointer (or an object that is convertible to one). You will get a function object. And no amount of casting is going to allow you to pass that tomakecontext. Not in any way that actually works.According to N3291, the most recent working draft of C++0x:
This is the only place where the specification allows conversion to a function pointer. Therefore, if recent versions of GCC do allow conversion to function pointers for [=], that not in accord with the specification.