[std::set] lambda as less predicate

Why this doesn't work?
1
2
3
4
auto less_fun = [](const Pair& l, const Pair& r)->bool{
			return l.second < r.second;
		};
		std::set<Pair, less_fun> sn;


output error:

error C2923: 'std::set' : 'less_fun' is not a valid template type argument for parameter '_Pr'


I am using VS 2012.

Thank you in advance.
'less_fun' is an object, an instance of a type of thing. You have avoided having to know its exact type by using the auto keyword.

The std::set takes two types as argument. 'Pair' is a type, but 'less_fun' is not -- it is an object.

Use decltype to get its type:

std::set<Pair, decltype(less_fun)> sn;


Personally, I prefer more_fun. :-)
I tried that before, but still doesnt work, error output:



error C3497: you cannot construct an instance of a lambda


Thank you for your time.
A lambda expression is always evaluated; it can not not appear in an unevaluated context. And it has no default constructor.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <set>
#include <functional>

int main()
{
    // sizeof( [] ( int v ) { return v ; } ) ; // error: expression is in unevaluated context
    // using x = decltype( [] ( int v ) { return v ; } ) ; // error: expression is in unevaluated context)

    auto lambda = [] ( int v ) { return v ; } ;

    sizeof(lambda) ; // ok, expression has been evaluated
    using y = decltype( lambda ) ; // ok, expression has been evaluated

    // y yy ; // error: a closure type has no default constructor (deleted)

    auto fun = [] ( int x, int y ) { return x%100 < y%100 ; } ;

    // std::set< int, decltype(fun) > set_one ; // error: no default constructor
    std::set< int, decltype(fun) > set_one(fun) ; // fine

    // recommended 
    std::set< int, std::function< bool(int,int) > > set_two(
                                            [] ( int x, int y ) { return x>y ; } ) ; // fine
}
Last edited on
You need to pass less_fun as argument to the constructor.
std::set<Pair, decltype(less_fun)> sn(less_fun);
Thank you all.

Works with std::function but still not with decltype:

@JLBorges
 
std::set< int, decltype(fun) > set_one(fun) ; // fine 



Got same error as before.

Thank you for your time.

EDIT: Works with Mingw 4.6.2 but not with VS2012
Last edited on
@JLBorges
sizeof(lambda) ; // ok, expression has been evaluated


The sizeof operator does not evaluate expressions.
> The sizeof operator does not evaluate expressions.

Yes, it does not. Which is why I used the the present perfect non-progressive tense "has been evaluated" (to indicate a past action that has an influence on the present).

Perhaps it would have made things clearer if the past perfect non-progressive tense was used instead, and if it was clarified that the expression being discussed is the lambda expression. ("the lambda expression had been evaluated")
Topic archived. No new replies allowed.