I am playing around with the c++11 functional features. One thing I find odd is that the type of a lambda function is actually NOT a function<> type. What's more, lambda's do not seem to play really well with the type-inferencing mechanism.
Attached is a small example in which I tested flipping the two arguments of a function for adding two integers. (The compiler I used was gcc 4.6.2 under MinGW.) In the example, the type for addInt_f
has been explicitly defined using function<> while addInt_l
is a lambda whose type is type-inferenced with auto
.
When I compiled the code, the flip
function can accept the explicitly type-defined version of addInt but not the lambda version, giving an error saying that,
testCppBind.cpp:15:27: error: no matching function for call to 'flip(<lambda(int, int)>&)'
The next few lines show that the lambda version (as well as a 'raw' version) can be accepted if it's explicitly cast to the appropriate function<> type.
So my questions are:
Why is it that a lambda function does not have a
function<>
type in the first place? In the small example, why does notaddInt_l
havefunction<int (int,int)>
as the type instead of having a different,lambda
type? From the perspective of functional programming, what's the difference between a function/functional object and a lambda?If there is a fundamental reason that these two have to be different. I heard that lambda's can be converted to
function<>
but they are different. Is this a design issue/defect of C++11, an implementation issue or is there a benefit in distinguishing the two as the way it is? It seems that the type-signature ofaddInt_l
alone has provided enough information about the parameter and return types of the function.Is there a way to write the lambda so that the above mentioned explicit type-casting can be avoided?
Thanks in advance.
//-- testCppBind.cpp --
#include <functional>
using namespace std;
using namespace std::placeholders;
template <typename T1,typename T2, typename T3>
function<T3 (T2, T1)> flip(function<T3 (T1, T2)> f) { return bind(f,_2,_1);}
function<int (int,int)> addInt_f = [](int a,int b) -> int { return a + b;};
auto addInt_l = [](int a,int b) -> int { return a + b;};
int addInt0(int a, int b) { return a+b;}
int main() {
auto ff = flip(addInt_f); //ok
auto ff1 = flip(addInt_l); //not ok
auto ff2 = flip((function<int (int,int)>)addInt_l); //ok
auto ff3 = flip((function<int (int,int)>)addInt0); //ok
return 0;
}