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