How to use a lambda expression as a template parameter?

19,599

Solution 1

The 2nd template parameter of std::set expects a type, not an expression, so it is just you are using it wrongly.

You could create the set like this:

auto comp = [](const A& lhs, const A& rhs) -> bool { return lhs.x < rhs.x; };
auto SetOfA = std::set <A, decltype(comp)> (comp);

Solution 2

Not sure if this is what you're asking, but the signature of a lambda which returns RetType and accepts InType will be:

std::function<RetType(InType)>

(Make sure to #include <functional>)

You can shorten that by using a typedef, but I'm not sure you can use decltype to avoid figuring out the actual type (since lambdas apparently can't be used in that context.)

So your typedef should be:

typedef std::function<bool(const A &lhs, const A &rhs)> Comp

or

using Comp = std::function<bool(const A &lhs, const A &rhs)>;
Share:
19,599
Admin
Author by

Admin

Updated on June 02, 2022

Comments

  • Admin
    Admin almost 2 years

    How to use lambda expression as a template parameter? E.g. as a comparison class initializing a std::set.

    The following solution should work, as lambda expression merely creates an anonymous struct, which should be appropriate as a template parameter. However, a lot of errors are spawned.

    Code example:

    struct A {int x; int y;};
    std::set <A, [](const A lhs, const A &rhs) ->bool {
        return lhs.x < rhs.x;
        } > SetOfA;
    

    Error output (I am using g++ 4.5.1 compiler and --std=c++0x compilation flag):

    error: ‘lhs’ cannot appear in a constant-expression
    error: ‘.’ cannot appear in a constant-expression
    error: ‘rhs’ cannot appear in a constant-expression
    error: ‘.’ cannot appear in a constant-expression
    At global scope:
    error: template argument 2 is invalid
    

    Is that the expected behavior or a bug in GCC?

    EDIT

    As someone pointed out, I'm using lambda expressions incorrectly as they return an instance of the anonymous struct they are referring to.

    However, fixing that error does not solve the problem. I get lambda-expression in unevaluated context error for the following code:

    struct A {int x; int y;};
    typedef decltype ([](const A lhs, const A &rhs) ->bool {
        return lhs.x < rhs.x;
        }) Comp;
    std::set <A, Comp > SetOfA;