简体   繁体   中英

How do achieve this comparison in STL priority_queue inside C++ Class

This is NOT a duplicate question It differs here as the comparison function has a dependancy on the main class.

All my logic is in a class. I have a map nodeCnt which can be looked up upon getCnt() . I am figuring out for how to have a custom comparison myCmp for my priority queue pq which will do comparison based on the map.

The following snippet does not work. And having auto cmp as described in reference docs cannot be done as Class cannot have such declarations for comparison function.

Class AllLogic {

 private:
   std::map<int, int> nodeCnt;

   // This is my confusing part
   std::priority_queue<int, std::vector<int>, decltype(&myCmp)> pq(&myCmp);

 public:

   int getCnt(int val) {
     if (nodeCnt.find(val) != nodeCnt.end())
         return nodeCnt[val];  
      return 0;
    }

  bool myCmp(int left, int right) {
     return getCnt(left) < getCnt(right);
  } 
};

Make a struct like this:

// forward declare your class, because the comparator will use it
class AllLogic;

struct MyCompareT
{
    AllLogic* object;
    bool operator()(int left, int right) const;
};

// after AllLogic has been defined
bool MyCompareT::operator()(int left, int right) const {
    return object->myCmp(left, right);
}

And your priority_queue can be defined as:

std::priority_queue<int, std::vector<int>, MyCompareT> pq;

And initialized in the constructor like this:

AllLogic() :pq(MyCompareT{this}) {}

You can rework the code a bit to the following (note: the following is c++11):

#include <map>
#include <queue>

The comparison functor takes a reference to the map, and uses it to compare:

struct myCmp {
    explicit myCmp(std::map<int, int> &nodeCnt) : nodeCnt_{&nodeCnt} {}

    bool operator()(int lhs, int rhs) const {
        auto lhs_it = nodeCnt_->find(lhs);
        auto rhs_it = nodeCnt_->find(rhs);
        auto lhs_val = lhs_it == nodeCnt_->end()? 0: lhs_it->second;
        auto rhs_val = rhs_it == nodeCnt_->end()? 0: rhs_it->second;
        return lhs_val < rhs_val; 
    }

private:
   std::map<int, int> *nodeCnt_;
};

The class sets the map, then the comparison functor, then the queue; each one uses the previous one:

class AllLogic {
private:
   std::map<int, int> nodeCnt;
   myCmp myCmp_{nodeCnt};
   std::priority_queue<int, std::vector<int>, myCmp> pq{myCmp_};
};

int main(){}

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