122

我正在尝试声明一个priority_queue of nodes,bool Compare(Node a, Node b)用作比较器函数(它在节点类之外)。

我目前拥有的是:

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

4

11 回答 11

152

注意 - 您可能还想查看其他答案,尤其是带有 decltype 和 lambda 的答案


您应该像这样声明一个类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;
}
于 2013-04-19T18:38:06.797 回答
84

接受的答案显示了如何使用类或 astd::function作为比较器。我们也可以传递一个函数指针,正如cute_ptr's answer已经显示的那样。但是,这样做的语法比那里显示的要简单得多:

class Node;
bool Compare(Node a, Node b);

std::priority_queue<Node, std::vector<Node>, decltype(&Compare)> openSet(Compare);

也就是说,不需要显式编码函数的类型,您可以让编译器使用decltype.

如果比较器是 lambda,这将非常有用。除了使用之外,您不能以任何其他方式指定 lambda 的类型decltype。例如:

auto compare = [](Node a, Node b) { return a.foo < b.foo; }
std::priority_queue<Node, std::vector<Node>, decltype(compare)> openSet(compare);
于 2018-02-02T17:15:18.160 回答
23

The third template parameter must be a class who has operator()(Node,Node) overloaded. So you will have to create a class this way:

class ComparisonClass {
public:
    bool operator() (Node, Node) {
        //comparison code here
    }
};

And then you will use this class as the third template parameter like this:

priority_queue<Node, vector<Node>, ComparisonClass> q;
于 2013-04-19T18:46:18.397 回答
14

直接回答你的问题:

我正在尝试声明一个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)

于 2016-11-13T11:19:57.353 回答
9

您必须先定义比较。有 3 种方法可以做到这一点:

  1. 使用类
  2. 使用结构(与类相同)
  3. 使用 lambda 函数。

使用类/结构很容易,因为很容易声明,只需在执行代码上方写下这行代码

struct compare{
  public:
  bool operator()(Node& a,Node& b) // overloading both operators 
  {
      return a.w < b.w: // if you want increasing order;(i.e increasing for minPQ)
      return a.w > b.w // if you want reverse of default order;(i.e decreasing for minPQ)
   }
};

调用代码:

priority_queue<Node,vector<Node>,compare> pq;
于 2020-09-17T21:39:00.090 回答
6

也可以使用 lambda 函数。

auto Compare = [](Node &a, Node &b) { //compare };
std::priority_queue<Node, std::vector<Node>, decltype(Compare)> openset(Compare);
于 2019-04-13T12:10:35.097 回答
4

如果这对任何人都有帮助:

static bool myFunction(Node& p1, Node& p2) {}
priority_queue <Node, vector<Node>, function<bool(Node&, Node&)>> pq1(myFunction);
于 2020-07-17T13:46:55.897 回答
2

在优先级队列中,有一个预定义的布尔函数“operator<()”,请尝试根据您的要求重载该函数。

bool operator<(const Node& x,const Node& y){
    return x.data>y.data;
}

priority_queue<Node> min_heap;
于 2021-09-16T04:39:07.857 回答
1

使用最新的 c++ 标准,您实际上可以为比较器声明一个 lambda 函数,这将使代码更加简洁。这是一个示例代码:

#include <queue>

class Foo
{
    public:
        int i;
};


int main()
{
    auto comparator = [](const Foo& a, const Foo& b) {
        return a.i > b.i;
    };

    std::priority_queue<Foo, std::vector<Foo>, decltype(comparator)>  pq(comparator);
    return 0;
}
于 2021-04-05T13:02:38.970 回答
0

更喜欢 struct,这就是 std::greater 所做的

struct Compare {
  bool operator()(Node const&, Node &) {}
}
于 2019-11-23T17:58:59.747 回答
0

借助struct也我们可以做到这一点。代码将如下所示。

struct myCompare{
    bool operator()(Node &a, Node &b){
        // Your own custom logic to compare the two nodes and return a boolean value.
    }
}

priority_queue<Node, vector<Node>, myCompare> openSet;
于 2021-09-23T18:40:39.823 回答