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

Объявление 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?

4b9b3361

Ответ 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;
}