【问题标题】:Operator== overloading of an abstract class and shared_ptrOperator== 抽象类和 shared_ptr 的重载
【发布时间】:2016-04-12 07:21:27
【问题描述】:

我想在一个抽象类的shared_ptr 列表中使用std::find,但出现错误。有没有办法通过在std::find 中取消引用来比较两个shared_ptr

是否有可能交一个朋友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==

【问题讨论】:

  • 但它是在 shared_ptr::operator == () 方面比较的
  • @DieterLücking 我不明白。
  • 尝试定义bool operator==(const std::shared_ptr&lt;A&gt; &amp;sp, const Point &amp;point){return ((*sp) == point);}
  • @Rames 说它的参数太多了。
  • @kuhaku 你在课外声明了吗?它不能是类成员。

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


【解决方案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,当使用 find(l.begin(), l.end(), p) 时,它转换为 shared_ptr&lt;A&gt; == Point。因为它将使用shared_ptr&lt;A&gt;::operator==,所以你将使用std::find_if并编写一个自定义的比较函数/函子,可以比较这两种类型并将其传递给find

您可以在以下位置了解有关函子的更多信息:C++ Functors - and their uses

【讨论】:

  • 或将特殊功能传递给find
  • 我对函子一无所知,find 的特殊函数必须是函子吗?
  • @kuhaku 不必如此。您也可以创建一个普通函数并将其传递给find。建议使用仿函数,因为它们可以内联,这可以使代码更快。
  • 据我所知,比较函数不能作为find的参数。 cplusplus.com/reference/algorithm/find
【解决方案2】:

问题:

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

【讨论】:

  • 它编译。我知道 lambda 函数很酷,可惜我们的教练放弃了它们,我现在要阅读它们。
  • 是的,lambda 绝对很酷。以quick intro 开头。
猜你喜欢
  • 2021-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-28
  • 2019-09-05
  • 2010-12-14
  • 1970-01-01
相关资源
最近更新 更多