运算符==重载抽象类和shared_ptr

时间:2016-01-07 18:54:39

标签: c++ c++11 polymorphism operator-overloading shared-ptr

我想在std::find抽象类的列表中使用shared_ptr,但是我收到了错误。有没有办法比较两个shared_ptr std::find中取消引用它们?

是否有可能让朋友operator==超载shared_ptr<A>

最小例子:

#include "point.h"
#include <list>
#include <algorithm>
#include <memory>

using namespace std;

class A {

protected:
    Point loc;
public:

    virtual void foo() = 0;

    virtual bool operator==(const Point& rhs) const = 0;
};

class B: public A {
    virtual void foo() override{}

    virtual bool operator==(const Point& rhs) const override {
        return rhs == loc;
    }
};

class C {

    list<shared_ptr<A>> l;
    void bar(Point & p) {

        const auto & f = find(l.begin(), l.end(), p); //<-- error is from here
    }
};
  

错误C2679二进制'==':找不到哪个运算符采用'const Point'类型的右手操作数(或者没有可接受的转换)

注意:Point已有operator==

2 个答案:

答案 0 :(得分:5)

问题:

find() 旨在在迭代器范围内找到一个精确的

您已定义operator==以将APoint进行比较。但是您的列表不包含A个对象,而是共享指向A个对象的指针。不幸的是,将共享指针与Point进行比较并不是定义的。这种不匹配会导致您报告的错误。

解决方案:

一个简单的解决方案是使用 find_if() 而不是find():它不会寻找精确的值,而是让谓词变为真:

   const auto & f = find_if(l.begin(), l.end(),[p](shared_ptr<A> &a){ return *a==p; });

答案 1 :(得分:1)

std::find可以实现为

template<class InputIt, class T>
InputIt find(InputIt first, InputIt last, const T& value)
{
    for (; first != last; ++first) {
        if (*first == value) {
            return first;
        }
    }
    return last;
}

正如您所看到的那样,在使用*first == value时,会将shared_ptr<A> == Pointfind(l.begin(), l.end(), p)进行比较。由于它将使用shared_ptr<A>::operator==,您将使用std::find_if并编写自定义比较函数/仿函数,可以比较这两种类型并将其传递给find

您可以在C++ Functors - and their uses

了解有关仿函数的更多信息