Подтвердить что ты не робот

С++ priority_queue с ошибкой компаратора лямбды

У меня есть следующий ошибочный код, который я пытаюсь скомпилировать в VC2010, но я получаю сообщение об ошибке C2974, это происходит только тогда, когда я включают выражение лямбда, поэтому я предполагаю, что это как-то связано с этим.

typedef pair<pair<int, int>, int> adjlist_edge;
priority_queue< adjlist_edge , vector<adjlist_edge>,
    [](adjlist_edge a, adjlist_edge b) -> bool {
        if(a.second > b.second){ return true; } else { return false; }
    }> adjlist_pq;

Я знаю, что форма определения шаблона верна как

priority_queue<int , vector<int>, greater<int>> pq;

Работает так, как ожидалось. Любые идеи, что я делаю неправильно? Что-то явно не так с лямбдой, которая выглядит неправильно, что я мог бы не заметить? Спасибо за чтение!

4b9b3361

Ответ 1

Сначала определите лямбда-объект, затем передайте его типу шаблона с помощью decltype, а затем передайте его непосредственно конструктору.

auto comp = []( adjist a, adjlist b ) { return a.second > b.second; };
priority_queue< adjlist_edge , vector<adjlist_edge>, decltype( comp ) >
     adjlist_pq( comp );

Ответ 2

priority_queue принимает компаратор как аргумент шаблона. Лямбда-функции являются объектами и поэтому не могут использоваться в качестве аргументов шаблона (только очень немногие типы могут быть, среди них интегральными типами).

Вы можете попробовать использовать decltype там:

priority_queue< adjlist_edge , vector<adjlist_edge>,
               decltype( [](adjlist_edge a, adjlist_edge b) -> bool {
                if(a.second > b.second){ return true; } else { return false; }
               })>
adjlist_pq( [](adjlist_edge a, adjlist_edge b) -> bool {
                if(a.second > b.second){ return true; } else { return false; }
             } );

В противном случае (и) вы можете использовать function<>:

priority_queue< adjlist_edge , vector<adjlist_edge>,
                function<bool(adjlist_edge,adjlist_edge)> >
adjlist_pq( [](adjlist_edge a, adjlist_edge b) -> bool {
                if(a.second > b.second){ return true; } else { return false; }
            } );