简体   繁体   中英

C++ overloading > for priority_queue (min heap): yields “invalid operands to binary expression ('const Node' and 'const Node')” on push() for heap

I am trying to overload the > operator so I can do this for a priority queue:

priority_queue<Node, vector<Node>, greater<Node> > unexplored_nodes;

I would like to use it as a min-heap.

This is the code for the Node struct (I know, it's not best to have a struct with public variables, but I just wanted something quick and dirty):

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
}

This is how I am compiling it:

clang++ -std=c++11 -stdlib=libc++ thefile.cc

In all 3 of the ways I tried, some error appeared (commented in the code). I had looked at Creating Min Heap from STL Priority Queue for ways to implement it (I tried the one by larsmans), but they haven't worked.

If anyone can help, I would appreciate it. (Also if you have a better way to use the priority queue as a min heap that avoids operator overloading, that would be good too... this is the main purpose.)

You must mark the operator as const :

 bool operator> (const Node &rhs) const {
   return d > rhs.d;
 }

EDIT

If you don't want to overload operators, you can provide your own comparator to the queue:

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]);
}

EDIT 2

Here's how you could use a custom map:

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]);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM