Чистый способ поместить лямбду в определение класса - PullRequest
4 голосов
/ 05 ноября 2019

У меня есть код, который прекрасно работает в локальной функции:

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);
    // ...
}

Теперь я хотел бы переместить мою переменную sieve в класс. Я могу написать следующее чудовище:

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);
};

Можно ли как-нибудь написать эту конструкцию по умолчанию без указания типа дважды? Или просто чище.

Ответы [ 2 ]

6 голосов
/ 05 ноября 2019

Можно ли как-нибудь написать эту конструкцию по умолчанию без указания типа дважды?

Да , вы можете!

Использовать braced-init-list (или равномерное инициирование) для инициализации члена std::priority_queue класса Bar.

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
};

Или просто предоставьте функтор сравнения, с помощью которого вы можете избежать передачи объекта компаратора конструктору 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
};
2 голосов
/ 05 ноября 2019

Для полноты картины и для предоставления ответа, который буквально принимает вопрос в заголовке, вы можете позволить функции-члену возвращать лямбду:

#include <iostream>

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

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

Я бы использовал это, когда лямбда не можетбыть статичнымТем не менее, для кода, который вы разместили, я бы определенно предпочел решение с лямбда-выражением в качестве статического члена и демонстрозитизацию кода с помощью равномерной инициализации (как обрисовано в общих чертах в ответе).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...