Search code examples
c++dictionaryhashmappriority-queue

How to create and use a map of priority queues with a custom comparator?


For context, I would like to create an "order backlog" where I have a map of string keys(symbol) and the value would be a priority queue, which contains all the orders for that symbol in a prioritized manner.

My custom comparator, which takes in a boolean since buy orders and sell orders have the oppposite prioritization:

struct Compare{
    bool buySide;
    Compare(bool side) : buySide(side) {}
    bool operator()(pair<int, float> order1, pair<int, float> order2) {
        if (buySide) {
            return order1.second < order2.second;
        }
        return order1.second > order2.second;
    };
};

I'm trying to create a map like so:

typedef priority_queue<pair<int, float>, vector<pair<int, float>>, Compare> priorityQueue;
map<string, priorityQueue> marketBuys;

and then using it like so:

if (marketBuys.find(order.symbol) == marketBuys.end()) {
    marketBuys[order.symbol] = priorityQueue(Compare(true));
}
marketBuys[order.symbol].push(make_pair(order.orderId, order.price));

However, I don't think I'm creating the priority queue correctly, and the important part is I need to somehow instantiate the priority queue with the correct prioritization, so I have to use the comparator constructor. I'm getting errors like

error: no matching function for call to ‘std::priority_queue<std::pair<int, float>, std::vector<std::pair<int, float> >, Compare>::priority_queue()’

If I just wanted a standalone priority queue, I would create it like so:

priority_queue<pair<int, float>, vector<pair<int, float>>, Compare> priorityQueue(Compare(true));

But I can't figure out how to put those inside maps. I also tried:

if (marketBuys.find(order.symbol) == marketBuys.end()) {
    priorityQueue pq(Compare(true));
    marketBuys[order.symbol] = pq;
}
marketBuys[order.symbol].push(make_pair(order.orderId, order.price));

which also didn't work.


Solution

  • The std::map<>::operator[] need the objet to be default constructible. Here you can't use this operator. Other map functions are accessible.

       auto fd = marketBuys.find(order.symbol);
       if ( fd == marketBuys.end() ) {
          fd = marketBuys.emplace(order.symbol, priorityQueue(Compare(true))).first;
       }
       fd->second.push(std::make_pair(order.orderId, order.price));