Объявление priority_queue в С++ с помощью пользовательского компаратора
Я пытаюсь объявить priority_queue of nodes
, используя bool Compare(Node a, Node b)
как функцию компаратора (которая находится вне класса node).
В настоящее время у меня есть:
priority_queue<Node, vector<Node>, Compare> openSet;
По какой-то причине я получаю Error: "Compare" is not a type name
Изменение объявления на priority_queue <Node, vector<Node>, bool Compare>
дает мне Error: expected a '>'
Я также пробовал:
priority_queue<Node, vector<Node>, Compare()> openSet;
priority_queue<Node, vector<Node>, bool Compare()> openSet;
priority_queue<Node, vector<Node>, Compare<Node, Node>> openSet;
Как правильно объявить мой priority_queue
?
Ответы
Ответ 1
Вы должны объявить класс Compare
и перегрузить operator()
для него следующим образом:
class Foo
{
};
class Compare
{
public:
bool operator() (Foo, Foo)
{
return true;
}
};
int main()
{
std::priority_queue<Foo, std::vector<Foo>, Compare> pq;
return 0;
}
Или, если вы по каким-то причинам не можете сделать это как класс, вы можете использовать std::function
для него:
class Foo
{
};
bool Compare(Foo, Foo)
{
return true;
}
int main()
{
std::priority_queue<Foo, std::vector<Foo>, std::function<bool(Foo, Foo)>> pq(Compare);
return 0;
}
Ответ 2
Третий параметр шаблона должен быть классом с перегруженным operator()(Node,Node)
.
Таким образом, вам придется создать класс следующим образом:
class ComparisonClass {
bool operator() (Node, Node) {
//comparison code here
}
};
И тогда вы будете использовать этот класс в качестве третьего параметра шаблона следующим образом:
priority_queue<Node, vector<Node>, ComparisonClass> q;
Ответ 3
Принятый ответ заставляет вас поверить, что вы должны использовать класс или std::function
в качестве компаратора. Это неправда! ответ cute_ptr показал, как передать функцию конструктору, но есть более простой способ:
priority_queue<Node, vector<Node>, decltype(&Compare)> openSet(Compare);
То есть, нет необходимости явно кодировать тип функции, вы можете позволить компилятору сделать это для вас.
Ответ 4
Отвечая на ваш вопрос напрямую:
Я пытаюсь объявить priority_queue
узлов, используя bool Compare(Node a, Node b) as the comparator function
В настоящее время у меня есть:
priority_queue<Node, vector<Node>, Compare> openSet;
По какой-то причине я получаю сообщение об ошибке:
"Compare" is not a type name
Компилятор сообщает вам, что именно: Compare
- это не имя типа, а экземпляр функции, которая принимает два Nodes
и возвращает bool
.
Вам нужно указать тип указателя функции:
std::priority_queue<Node, std::vector<Node>, bool (*)(Node, Node)> openSet(Compare)
Ответ 5
Можно также использовать лямбда-функцию.
auto Compare = [](Node &a, Node &b) { //compare };
std::priority_queue<Node, std::vector<Node>, decltype(Compare)> openset(Compare);
Ответ 6
Вы можете просто изменить свою декларацию на
priority_queue<Node, vector<Node>, bool (*)(Node, Node)> openSet(Compare);
Третий параметр требует типа, поэтому указатель функции будет работать, но мы всегда должны openSet(Compare)
компилятору, где найти функцию, как в openSet(Compare)
.
Вот полный пример:
using namespace std;
class Foo {};
bool cmp(const Foo& a, const Foo& b) { return true; }
int main() {
priority_queue<Foo, vector<Foo>, bool (*)(const Foo&, const Foo&)> data(cmp);
data.push(Foo());
return 0;
}