I have this current setup:
#include <iostream>
#include <queue>
#include <vector>
class A
{
int val;
public:
A()
{
std::cout << "Inside A. Constructor with val =" << val << ".\n";
}
A(const A& msg)
{
std::cout << "Inside const A. Never want to come here. val =" << msg.val << ".\n";
}
bool operator()(const A* m1, const A* m2)
{
std::cout << "Inside () function.\n";
std::cout << "m1: " << m1->GetVal() << " m2: " << m2->GetVal()<<"\n";
return (m1->GetVal() < m2->GetVal());
}
void setVal(int input) { std::cout << "inside setVal.\n"; val = input; }
int GetVal()const { return val; }
};
void specialPriorityQueue()
{
//init
A* val = new A();
val->setVal(5);
std::priority_queue<A*, std::vector<A*>, A> pq;
pq.push(val);
A* val2 = new A();
val2->setVal(3);
pq.push(val2);
delete val;
delete val2;
}
int main()
{
specialPriorityQueue();
return 0;
}
outputs:
Inside A. Constructor with val =-85000000...
inside setVal.
Inside A. Constructor with val =-85000000...
Inside const A. Never want to come here. val =-85000000....
Inside A. Constructor with val =-85000000...
inside setVal.
Inside const A. Never want to come here. val =-85000000....
Inside () function.
m1: 5 m2: 3
My question is: Is there any way to avoid using the copy constructor by the priority queue. This causes undefined behaviour. I can't remove the function either as it has too much dependencies elsewhere.
That copy constructor is called when it creates the comparator object, which is also your element type, A
.
Use another type for comparator, e.g.:
struct Compare
{
bool operator()(const A* m1, const A* m2) const {
return m1->GetVal() < m2->GetVal();
}
};
And then:
std::priority_queue<A*, std::vector<A*>, Compare> pq;
And, even better, use smart pointers to avoid memory leaks:
struct Compare
{
bool operator()(std::unique_ptr<A> const& m1, std::unique_ptr<A> const& m2) const {
return m1->GetVal() < m2->GetVal();
}
};
void specialPriorityQueue() {
std::unique_ptr<A> val(new A());
val->setVal(5);
std::priority_queue<std::unique_ptr<A>, std::vector<std::unique_ptr<A>>, Compare> pq;
pq.push(move(val));
std::unique_ptr<A> val2(new A());
val2->setVal(3);
pq.push(move(val2));
}