c – 无法将派生的Compare传递给std :: priority_queue

前端之家收集整理的这篇文章主要介绍了c – 无法将派生的Compare传递给std :: priority_queue前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我需要将派生的比较器传递给std :: priority_queue,但由于某种原因,正在调用基类’operator().

这是一个显示此行为的最小代码

class Base {
    public:
    virtual bool operator() (int l,int r) const {
        cout << "Should not be called" << std::endl;
        return 0;
    }
    virtual ~Base() {}
};
class A : public Base { 
    public:
    bool operator() (int l,int r) const override {
        cout << "Should be called!!!!";
        return l < r;
    }
};
int main() {
    priority_queue<int,vector<int>,Base> pq((A()));
    pq.push(1);
    pq.push(2);
    pq.push(3);
    pq.push(0);
    cout << pq.top();
    return 0;
}

The code is available on ideone as well

请注意,我不能使用priority_queue< int,vector< int>,A>,因为我有Base的其他子类,这将导致大量代码重复1.

我究竟做错了什么?如何将比较器传递给将在其生命周期内使用的priority_queue?

(1)我知道我可以通过使用接受priority_queue< int,T>的模板函数来绕过代码复制问题. – 但我真的不愿意.

解决方法

该标准指定比较comp作为23.6.4.1中类模板的值成员.据说构造函数

Initializes comp with x and c with y (copy constructing or move
constructing as appropriate);

因此你有切片,即使参数类型实际上是一个const比较&amp ;.

解决这个问题,你可以为比较器实现一个pimpl-wrapper.这个包装器将在内部保持Base&到实际的比较器,在它的非虚拟运算符()中只需调用Base / A比较器的虚拟运算符().

请仔细考虑A对象的生命周期.根据比较器所需的状态,您可以在Base中实现virtual clone-method.并将Base保留为std :: unique_ptr< Base>在你的PimplCompare中 – 你克隆它的副本.或者你把它保存为std :: shared_ptr< Base>.

猜你在找的C&C++相关文章