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

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

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

  1. class Base {
  2. public:
  3. virtual bool operator() (int l,int r) const {
  4. cout << "Should not be called" << std::endl;
  5. return 0;
  6. }
  7. virtual ~Base() {}
  8. };
  9. class A : public Base {
  10. public:
  11. bool operator() (int l,int r) const override {
  12. cout << "Should be called!!!!";
  13. return l < r;
  14. }
  15. };
  16. int main() {
  17. priority_queue<int,vector<int>,Base> pq((A()));
  18. pq.push(1);
  19. pq.push(2);
  20. pq.push(3);
  21. pq.push(0);
  22. cout << pq.top();
  23. return 0;
  24. }

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++相关文章