Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clean way to put lambda in class definition

I have code that works just fine, in a local function:

struct Divider
{
public:
    size_t factor;
    size_t next;
};

void foo()
{
    auto cmp = [](const Divider& x, const Divider& y) { return x.next > y.next; };
    std::priority_queue < Divider, std::vector<Divider>, decltype(cmp)> sieve(cmp);
    // ...
}

I would now like to move my sieve variable into a class. I can write the following monstrosity:

class Bar
{
    inline static auto cmp = [](const Divider& x, const Divider& y) { return x.next > y.next; };
    std::priority_queue < Divider, std::vector<Divider>, decltype(cmp)> sieve = std::priority_queue < Divider, std::vector<Divider>, decltype(cmp)>(cmp);
};

Is there any way I can write this default construction without specifying the type twice? Or just in a cleaner fashion.

like image 743
Jeffrey Avatar asked Dec 09 '25 13:12

Jeffrey


2 Answers

Is there any way I can write this default construction without specifying the type twice?

Yes, you can!

Use braced-init-list(or uniform-initiation) to initlize the std::priority_queue member of Bar class.

class Bar
{
    inline static auto cmp
        = [](const Divider& x, const Divider& y) { return x.next > y.next; };
    std::priority_queue<Divider, std::vector<Divider>, decltype(cmp)> sieve{ cmp };
           //                                                          ^^^^^^^^^^^^^ >> like this
};

Or simply provide a compare functor, by which you can avoid passing the comparator object to the constructor of the std::priority_queue.

class Bar
{
    struct Compare final // compare functor
    {
        bool operator()(const Divider& x, const Divider& y) const { 
            return x.next > y.next;
        }
    };
    std::priority_queue<Divider, std::vector<Divider>, Compare> sieve;
    //                                                 ^^^^^^^^^^^^^^^^^ >> like this
};
like image 143
JeJo Avatar answered Dec 12 '25 01:12

JeJo


For the sake of completeness and to provide an answer that takes the question in the title literally, you can let a member function return the lambda:

#include <iostream>

struct Bar {
    auto get_compare(){
        return [](){ std::cout << "hello world";};
    }
};

int main(){
    Bar b;
    b.get_compare()();
}

I'd use this when the lambda cannot be static. Though, for the code you posted I'd surely prefer the solution with the lambda as static member and de-monstrositizing the code by using uniform initialization (as outlined in the other answer).

like image 45
463035818_is_not_a_number Avatar answered Dec 12 '25 02:12

463035818_is_not_a_number



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!