jeudi 5 mars 2015

Lambda function, strange behavior

Let's assume we have the following lambda declared in the global namespace:



auto Less = [](int a,int b) -> bool
{
return a < b;
}


And the following code which make use of this lambda:



template<typename T>
struct foo
{
foo(int v){}
bool operator<(const foo<T>&) const
{
return T(1,2);
}
};

int main()
{
typedef foo<decltype(Less)> be_less;
priority_queue<be_less> data;
}


As you can see i use Less as template parameter for the struct foo. With g++4.9.2 this code does not compile:



test1.cpp:13:21: error: no matching function for call to '<lambda(int, int)>::__lambda0(int, int)'
return T(1,2);
^
test1.cpp:13:21: note: candidates are:
test1.cpp:17:14: note: constexpr<lambda(int, int)>::<lambda>(const<lambda(int, int)>&)
auto Less = [](int a,int b) -> bool
^
test1.cpp:17:14: note: candidate expects 1 argument, 2 provided
test1.cpp:17:14: note: constexpr<lambda(int, int)>::<lambda>(<lambda(int, int)>&&)
test1.cpp:17:14: note: candidate expects 1 argument, 2 provided


Bu i may fix this problem adding two small changes, first of all i change the lambda into this:



bool Less = [](int a,int b) -> bool
{
return a < b;
}


As you can see i just replaced auto with bool, this modification alone still does not work:



test1.cpp:13:21: error: expression list treated as compound expression in functional cast [-fpermiss
ive]
return T(1,2);


Unless i add -fpermissive, or i may change the operator< bool in this way:



bool operator<(const foo<T>&) const
{
return T((1,2));
}


Note the double parentheses. Now the code compile and everything work.


My question is, which is the technical reason why auto Less does not work but bool Less work?


I believe i know why the double parentheses are required in the second operator<, this should be to avoid the compiler to interpret T(1,2) as a declaration instead of a call.


Thanks for your time


Aucun commentaire:

Enregistrer un commentaire