为用户定义的对象重载operator ==

时间:2014-08-03 20:02:20

标签: c++

我有这段代码:

struct BoughtItemData
{
    uint64 m_playerGUID;
    uint32 m_itemEntryId;
    time_t m_date;

    BoughtItemData(uint64 playerGUID, uint32 itemEntryId, time_t date) : m_playerGUID(playerGUID), m_itemEntryId(itemEntryId), m_date(date) { }
    BoughtItemData(uint64 playerGUID) : m_playerGUID(playerGUID), m_itemEntryId(0), m_date(0) { }

    bool operator==(const BoughtItemData& other) const
    {
        return m_playerGUID == other.m_playerGUID;
    }
};

typedef std::list<BoughtItemData*> ShoppingCart;

其他地方我需要在ShoppingCart上使用std::find,因此我使用此代码:

const BoughtItemData current(player->GetGUID());

ShoppingCart::const_iterator itr = std::find(cart.begin(), cart.end(), current);
if (itr != cart.end())
//we have found something

我使用cart.push_back(new BoughtItemData(...))将新项目添加到列表中。

错误(二进制&#39; ==&#39;:找不到带有&#39; const BoughtItemData&#39;(或没有可接受的转换)类型的右手操作数的运算符)来自std::find行,我知道它没有做对,但我不知道该怎么做

3 个答案:

答案 0 :(得分:0)

问题是您的列表存储了指向BoughtItemData的指针,但您正在搜索BoughtItemData对象。解决方案是在列表中存储对象:

typedef std::list<BoughtItemData> ShoppingCart;

您还应该仔细考虑是否需要std::list而不是std::vector


如果你真的需要存储指针(我非常怀疑你这样做),那么你必须提供一个比较函子并将其传递给std::find_if。例如

auto cmp = [&current](const BoughtItemData* o)
           {
             return current.m_playerGUID == o->m_playerGUID;
           }

ShoppingCart::const_iterator itr = std::find_if(cart.begin(), cart.end(), cmp);

答案 1 :(得分:0)

您的设计存在根本性缺陷。您正在存储指向对象的指针,这很好,但可以避免。然后,您定义一个名为BoughItemData的新current,用于搜索。当然,current的地址永远不会出现在你的指针列表中。

例如,如果您的项目是复杂类型,您可以考虑使用std::map并搜索某个键。

答案 2 :(得分:0)

是的,你有相等比较运算符的重载。这意味着这样的代码将起作用:

BoughtItemData a,b;
bool is_equal = a == b;

但是,这不是您的编译错误所抱怨的。您的列表包含指针,而不是对象本身。现在,当你使用std :: find迭代它时,你实际上是在尝试执行这样的代码:

BoughtItemData current;
BoughtItemData* element_in_list;
bool is_equal = current == element_in_list;

你现在看到问题了吗?编译器需要一个比较运算符,用于比较指向对象的指针(暂时不要忘记const),唯一的运算符就是将一个对象与另一个对象进行比较。

那么,你如何解决这个问题呢? 您有三个主要选项:

  1. 提供一个可以使用指针的比较运算符(这就像一个创可贴)
  2. 更改列表以保存BoughtItemData类型的项目而不是指向它的指针
  3. 使用智能指针
  4. 当你选择做什么时,重要的是知道原因。

    为什么你首先使用指针?可能是因为您不想存储重复项。所以你需要问自己,这个列表是否是你将要存储BoughtItemData对象的唯一地方?如果是这样,那么将对象本身存储在列表中就完全没问题了。

    如果您有多个引用同一对象的数据结构,那么您需要指针。但是,不要使用原始指针,使用智能指针,其中最普遍的是shared pointer。共享指针将帮助消除与指针容器相关的生命周期管理的大量负担。

    即使你确实使用了共享指针,你仍然需要提供一个自定义函数来检查底层对象的相等性,因为STL容器仍然只会比较指针值。

    实际上,解决问题的最佳方案取决于您设计应用程序的方式。但是我可以给你一条建议:当你可以选择多种同样好的解决方案时,总是选择最简单的。这将使您的代码从长远来看更容易阅读,理解和维护。