我一直在尝试为 std::map 容器定义自定义比较器。
问题是:我可以中继 == 和 != 运算符,还是会破坏严格的弱顺序?我是否被迫使用运算符 <?
(一类和二类确实正确定义了 operator!= 和 operator==)
typedef std::pair<One, Two> MapKey_t;
class cmp
{
bool operator()(const MapKey_t& left, const MapKey_t& right) const
{ return left.first != right.first && right.first == right.second; }
}
typedef std::map<MapKey_t, Three*, cmp> MyMap_t;
因为左右切换不会改变比较器的返回值,这会起作用吗?
我真的不关心项目是如何分类到容器中的,但我不希望重复项成为其中的一部分。
更新:
我可以使用内存地址来获得严格的弱排序吗?
class cmp
{
bool operator()(const MapKey_t& left, const MapKey_t& right) const
{
if(left.first == right.first)
if(left.second != right.second)
return false; // This represents for me, functionally, a duplicate
else
// Can't use operator < there since left.second equals right.second but
// functionally for me, this is not a duplicate and should be stored
// what about memory address strict weak ordering ?
return &left < &right;
else
return left.first < right.first; // There I can use operator <
}
最佳答案
您不能依赖自洽的等于或不等于,因为它们没有建立严格的弱排序。如果您切换左右参数,比较器返回值应该改变。 map 必须能够建立元素的排序,而不仅仅是能够区分两个元素是否相等。
非常重要的是,是A < B
为真,则 B < A
是假的。此外,如果A < B
和 B < C
都为真,那么A < C
也是如此。
如果您不想或不能为您的类型建立严格的弱排序,那么您可以使用不需要它的映射: std::unordered_map
1,这是一个 HashMap 。但是,这将要求您提供散列函数和相等性比较。它还要求您的编译器支持 C++11。
1 正如@JohnDibling 在评论中指出的那样,std::unordered_map
不幸被命名。应该是std::hash_map
但显然这个名字可能与 hash_maps
冲突来自其他图书馆。在任何情况下,我们的目的不是要有一张未排序的 map ,而是要有一张可以不断查找的 map 。
关于c++ - std::map,自定义比较器的设计约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44481859/