std::map 不删除带有自定义对象的重复项
std::map not removing duplicates with custom object
all.
因此,我创建了一个可比较基类(a la Java(,它完成了重载C++比较运算符的工作。在这里:
template <class T>
class Comparable {
public:
bool operator== (const T& rhs) const { return this->compare(rhs) == 0; }
bool operator!= (const T& rhs) const { return !(*this == rhs); }
bool operator< (const T& rhs) const { return this->compare(rhs) < 0; }
bool operator<= (const T& rhs) const { return (*this == rhs) || (*this < rhs); }
bool operator> (const T& rhs) const { return this->compare(rhs) > 0; }
bool operator>= (const T& rhs) const { return (*this == rhs) || (*this > rhs); }
protected:
virtual int compare (const T& rhs) const = 0;
};
子类对象既有 ID,也有需要作为排序键的数据。我已经实现了每个,以便具有相同 ID 的对象返回 0,如果它们不是相同的 ID,它们会根据其数据进行排序。下面是一个示例:
int Foo::compare(const Foo& rhs) const
{
if (_id == rhs._id)
return 0;
// _value is integer data; comparison should sort on this
if (_value == rhs._value)
{
// OK, same data, now sort on ID's
return _id.compare(rhs._id);
}
// Sort on value
return _value - rhs._value;
}
到目前为止,我认为一切都很好。
但是,当我尝试将Foo对象存储在std::set容器中时,该集合不会消除重复项。也就是说,其中仍然会有包含相同 ID 的对象,即使这应该被视为相等。
有谁知道发生了什么?
编辑:关于为什么代码以这种方式设计有很多问题。
我需要满足两个条件:
- 无论值如何,具有相同 ID 的对象都必须被视为"相同"对象。
- 不具有相同 ID 的对象必须根据其值进行排序(该值是什么,取决于对象的类型(。
这是因为创建这些对象的数据来自未经验证的来源。如果该源提供的数据具有相同的 ID 但值不同,则为无效数据。
编辑2:关于std::map的严格弱排序。假设您有两个 Foo 对象,A 和 B。
如果你没有严格的弱排序,你就不能使用map
,如果你这样做了,你不能抱怨,它不起作用。这是map
的先决条件。
编辑:
您的compare
不会实现您指定的语义 - 如果在第二次测试中_value == rhs._value
,则应返回 0。
但是有了这个修复,你仍然没有一个一致的排序 - 参见本杰明林德利在评论中给出的例子。从本质上讲,您的排序没有意义 - 您要么需要修复语义,要么停止使用需要一致排序的标准库组件。
相关文章:
- 自定义对象的dlib序列化在gcc中失败
- 如何将带有自定义对象的容器从C++传递到QML
- 将 exprtk 与自定义类的对象一起使用
- 将 RTOS 队列对象封装在仅具有静态分配的 IQueue 自定义接口中
- 如何实现自定义匹配器以检查 Catch2 中的对象相等性
- 如何使用Q_PROPERTY公开自定义对象列表
- Qt5 远程对象 + 自定义类型,但不在 POD 中
- 从自定义类获取对象向量中的 max 元素
- 如何将来自 Boost.Python 的map_indexing_suite与自定义而不是标准对象一起使用?
- 如何在自定义对象的<<运算符中添加自定义前缀
- 如何使用 STL 排序对具有模板专用化的自定义类对象进行排序?
- 如何从 cpp 中的函数返回自定义类对象?
- 如何为自定义模板对象创建专门的函数模板
- 带有自定义deleter的std::unique_ptr对象的大小(一个由ref捕获的lambda)
- 基于3个对象的自定义排序
- 如何键入用于const对象的自定义io操纵器
- 指向临时对象的自定义迭代器(延迟加载)
- 将自定义对象作为参数从目标 C 传递到 C++
- 从 Arduino 中的自定义C++库构造对象时出错
- 从链表访问对象(自定义实现)