лямбда-функция не работает в priority_queue в c ++ (при использовании [&]) - PullRequest
0 голосов
/ 01 июня 2018

Когда я делаю Leetcode.com, следующий код не может быть скомпилирован.

auto cmp=[&](pair<int,int> a, pair<int,int> b){return heightMap[a.first]
         [a.second]<heightMap[b.first][b.second];};

priority_queue<pair<int,int>,vector<pair<int,int>>,decltype(cmp)> pq;

Хорошо работает, когда я использую

auto cmp=[](...){return true;}.

Но я должен использовать

auto cmp=[&](...){...}

, потому что мне нужен доступ к heightMap в функции.

Я не знаю, почему это не может быть скомпилировано

1 Ответ

0 голосов
/ 01 июня 2018

Я предполагаю, что вы работаете в области видимости блока (то есть внутри функции).

Правильный код - для случаев [&] и [] - должен быть:

priority_queue<pair<int,int>,vector<pair<int,int>>, decltype(cmp)> pq(cmp);
//                                                                   ^^^^^

Это можно увидеть в примере cppreference .

Если подумать, определение pq только с decltype(cmp) не может знать ни о какой локальной переменной- эта привязанность формируется только при фактическом создании cmp.


Причина в том, что конструктором по умолчанию для priority_queue является (C ++ 17 [priqueue.cons]):

explicit priority_queue(const Compare& x = Compare(), Container&& y = Container());

Как видите, это включает в себя значение по умолчанию-строительство объекта типа Compare.До C ++ 20 лямбды не могут быть конструктивными по умолчанию .

Конструкция лямбда без сохранения состояния по умолчанию была добавлена ​​ P0624 , которая не совсем попала в C ++ 17, но теперь появляется в черновиках C ++ 20.

Технически компилятор C ++ 17 должен отклонять даже версию [];но, похоже, некоторые компиляторы добились успеха в поддержке C ++ 20.

Я заметил, что clang ++ 6.0.0 фактически позволяет создавать лямбда-выражения, заданные как [&], по умолчанию, когда случается, что никакая переменная на самом деле не захвачена;в то время как формулировка P0624 гласит, что этот случай должен быть отклонен.Возможно, это изменится еще до того, как C ++ 20 будет завершен.

...