C ++避免使用由priorityqueue调用的复制构造函数

C++ Avoiding using copy constructor which is called by priorityqueue

我有这个当前设置:

#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;
    }

输出:

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

我的问题是:有没有办法避免优先队列使用拷贝构造函数。这会导致未定义的行为。我也无法删除该功能,因为它在其他地方有太多依赖项。

复制构造函数在创建比较对象时被调用,这也是您的元素类型,A

使用另一种类型作为比较器,例如:

struct Compare
{
    bool operator()(const A* m1, const A* m2) const {
        return m1->GetVal() < m2->GetVal();
    }
};

然后:

std::priority_queue<A*, std::vector<A*>, Compare> pq;

而且,更好的是,使用智能指针来避免内存泄漏:

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