繁体   English   中英

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

[英]overloading operator== for an user-defined object

我有以下代码:

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(...))将新项目添加到列表中。

错误(二进制'==':未找到采用类型为'const BoughtItemData'的右侧操作数(或没有可接受的转换)的运算符)来自std::find行,我知道它没有完成是的,但是我不确定该怎么做

问题是您的列表存储的是指向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);

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

您可以考虑使用std::map并在键上进行搜索,例如,如果您的商品是复杂类型。

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

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. 使用智能指针

当您选择做什么时,重要的是要知道为什么。

为什么首先使用指针? 可能是因为您不想存储重复项。 因此,您需要问问自己,该列表是否是将要存储BoughtItemData对象的唯一位置? 如果是这样,那么将对象本身存储在列表中就可以了。

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

即使您确实使用了共享指针,您仍然必须提供一个自定义函数来检查基础对象的相等性,因为STL容器仍将仅比较指针值。

因此,确实,解决问题的最佳解决方案取决于您设计应用程序的方式。 但是我可以给您提供一条建议: 当您选择看起来同样不错的多种解决方案时,请始终选择最简单的方案 从长远来看,这将使您的代码更易于阅读,理解和维护。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM