用于priority_queue(min heap)的C++重载>:在push()上为堆生成"无效操作数到二进制表达式('const Node'和'const Node')"

dmo*_*oly 2 c++ operator-overloading

我试图重载>运算符,所以我可以为优先级队列执行此操作:

priority_queue<Node, vector<Node>, greater<Node> > unexplored_nodes;
Run Code Online (Sandbox Code Playgroud)

我想用它作为最小堆.

这是Node结构的代码(我知道,最好有一个带有公共变量的结构,但我只想要快速和脏的东西):

struct Node {
  string repr;
  float d;
  vector<pair<Node, float> > neighbors;
  Node(string repr) {
    this->repr = repr;
    this->d = FLT_MAX;
  }

  // **All three of these forms yield errors**
  // Compiles without push() call below, but yields "invalids operands to binary expression" if I do have the push() call
  //bool operator()(const Node* lhs, const Node* rhs) const {
  //  return lhs->d > rhs->d;
  //}

  // Compiles without push() call below, but yields "invalids operands to binary expression" if I have do the push() call
  bool operator>(const Node &rhs) {
    return d > rhs.d;
  }

  // Error regardless of priority queue below: overloaded 'operator>' must be a binary operator (has 3 parameters)
  //bool operator>(const Node &lhs, const Node &rhs) {
  // return lhs.d > rhs.d;
  //}
};

void foo(const vector<Node> &list) {
  priority_queue<Node, vector<Node>, greater<Node> > q;
  q.push(list[0]); // this causes the 1st & 2nd overload attempt in the struct to have the "invalid operands" error
}
Run Code Online (Sandbox Code Playgroud)

这就是我编译它的方式:

clang++ -std=c++11 -stdlib=libc++ thefile.cc
Run Code Online (Sandbox Code Playgroud)

在我尝试的所有三种方式中,出现了一些错误(在代码中注释).我曾经看过从STL Priority Queue创建Min Heap的方法来实现它(我尝试了larsmans的那个),但它们没有用.

如果有人可以提供帮助,我将不胜感激.(另外如果你有一个更好的方法将优先级队列用作避免运算符重载的最小堆,那也很好......这是主要目的.)

Rei*_*ica 5

您必须将运营商标记为const:

 bool operator> (const Node &rhs) const {
   return d > rhs.d;
 }
Run Code Online (Sandbox Code Playgroud)

编辑

如果您不想重载运算符,可以将自己的比较器提供给队列:

struct Comparator
{
  bool operator() (const Node &lhs, const Node &rhs) const
  {
    return lhs.d > rhs.d;
  }
};

void foo(const vector<Node> &list) {
  priority_queue<Node, vector<Node>, Comparator> q;
  q.push(list[0]);
}
Run Code Online (Sandbox Code Playgroud)

编辑2

以下是您可以使用自定义地图的方法:

struct Comparator
{
  typedef std::map<Node, float> Map;

  explicit Comparator(const Map &map) : map(&map) {}

  bool operator() (const Node &lhs, const Node &rhs) const
  {
    return map->find(lhs)->second > map->find(rhs)->second;
  }

private:
  const Map *map;
};

void foo(const vector<Node> &list, const Comparator::Map &map) {
  priority_queue<Node, vector<Node>, Comparator> q(Comparator(map));
  q.push(list[0]);
}
Run Code Online (Sandbox Code Playgroud)

  • @dmonopoly这是优先级队列使用的比较器的要求.C++ 11,`[alg.sorting]§2`:"假设`comp`不会通过解引用的迭代器应用任何非常量函数." (2认同)