2
votes

Passing the lambda as function pointer works fine with gcc 4.6.3:

#example adapt from LoudNPossiblyWrong http://stackoverflow.com/questions/3351280/c0x-lambda-to-function-pointer-in-vs-2010
#include <iostream>

using namespace std;

void func(int i){cout << "I'V BEEN CALLED: " << i <<endl;}

void fptrfunc(void (*fptr)(int i), int j){fptr(j);}

int main(){
    fptrfunc(func,10); //this is ok
    fptrfunc([](int i){cout << "LAMBDA CALL " << i << endl; }, 20); //works fine
    return 0;
}

However passing the lambda as reference will not work:

#example adapt from LoudNPossiblyWrong http://stackoverflow.com/questions/3351280/c0x-lambda-to-function-pointer-in-vs-2010
#include <iostream>
using namespace std;

void func(int i){cout << "I'V BEEN CALLED: " << i <<endl;}

void freffunc(void (&fptr)(int i), int j){fptr(j);}

int main(){
    freffunc(func,10); //this is ok
    freffunc([](int i){cout << "LAMBDA CALL " << i << endl; }, 20); //DOES NOT COMPILE
    return 0;
}

error: invalid initialization of non-const reference of type ‘void (&)(int)’ from an rvalue of type ‘<lambda(int)>’

Can anyone explain why is that?

1
rvalue/temporary cannot bind to non-const reference - yngccc
Try adding an asterisk, like *[](int i){/*...*/}. No idea if that works... - Kerrek SB
@yngum, if this is the issue. I will expect the void (&&fptr)(int i) solve the problem. But it does not. @Kerrek, this actually works. Maybe this is because @Angew said, the closure object has conversion operator from closure=>pointer but not closure=>reference? - Wang

1 Answers

1
votes

A lambda is not really a function, it's a closure object. Basically, a compiler-generated class with operator() defined. A non-capturing closure also defines a conversion operator for converting to good old pointer-to-function.