Liza
Liza

Reputation: 103

Passing custom priority queue by reference

I can't pass (custom) priority_queue reference. Priority queue was customized using lambda. Is there any workaround? I tried using functors and all that, but none of them would let me go past line with the priority_queue creation at all without failing on the compilation step with various issues where priority_queue constructor wouldn't accept the sorting method. I guess it cannot reach the lambda or it just needs some special type declaration in the header, but I can't figure it out

Here is a simplified version of my code.

#include <queue>
#include <memory>

struct Node
{
  int full_dist,
      dist1,
      dist2;

  Node(int d1, int d2) { full_dist = d1 + d2; }
};

void some_processing(std::priority_queue<std::shared_ptr<Node>>& nodes)
{
  //something being done with the queue
}

int main()
{
  auto comp = [] (const std::shared_ptr<Node>& l, const std::shared_ptr<Node> r) -> bool 
    { return l->full_dist > r->full_dist; };

  std::priority_queue<std::shared_ptr<Node>, std::vector<std::shared_ptr<Node>>, decltype(comp)> nodes(comp);
  some_processing(nodes);//breaks here
}

Here is the error I've got on this example:

test.cpp:24:24: error: invalid initialization of reference of type ‘std::priority_queue<std::shared_ptr<Node> >&’ 
from expression of type ‘std::priority_queue<std::shared_ptr<Node>, std::vector<std::shared_ptr<Node>, std::allocator<std::shared_ptr<Node> > >, main()::__lambda0>’
some_processing(nodes);

Upvotes: 2

Views: 1987

Answers (2)

Sam Varshavchik
Sam Varshavchik

Reputation: 118340

Your priority queue is

std::priority_queue<std::shared_ptr<Node>,
             std::vector<std::shared_ptr<Node>>, decltype(comp)>

That's it's declared type. The parameter to your function is a reference to:

std::priority_queue<std::shared_ptr<Node>>

This is a completely different type. You can't pass a reference to one type to a function that expects a reference to a completely different type as a parameter. Each instance of a template class is unique. The difference between the first and the second class, here, is the same difference as a difference between class A and class B.

Upvotes: 0

Benjamin Lindley
Benjamin Lindley

Reputation: 103703

Make the function templated on the comparison type.

template<typename CompT>
void some_processing(
    std::priority_queue<std::shared_ptr<Node>,
                        std::vector<std::shared_ptr<Node>>,
                        CompT> & nodes)
{
    // something being done with the queue
}

Or keep things simple and just make the whole container type templated.

template<typename QueueT>
void some_processing(QueueT& nodes)
{
    // something being done with the queue
}

Upvotes: 1

Related Questions