C++ std::map:使用自定义运算符时更新密钥
当为C++ std::map:使用自定义运算符时更新密钥,c++,c++11,stl,std,stdmap,C++,C++11,Stl,Std,Stdmap,当为std::map使用自定义运算符时(设计时仅比较一些my KeyType的字段),两个对象KeyType k1、k2可能包含不同的数据,但对于map,它们看起来像相同的键。毕竟,这就是我们首先编写自定义比较器的原因 所以如果我写 map[k1] = 1; map[k2] = 2; 对于k1和k2,比较器报告它们相等,映射将包含键/值对{k1,2} 用{k2,2}替换成对的{k1,1}最优雅的方法是什么?还是先擦除k1,然后插入k2的唯一方法?我可以找到两种不同的方法,用等效密钥替换映射中的
std::map
使用自定义运算符时(设计时仅比较一些my KeyType的字段),两个对象KeyType k1、k2
可能包含不同的数据,但对于map,它们看起来像相同的键。毕竟,这就是我们首先编写自定义比较器的原因
所以如果我写
map[k1] = 1;
map[k2] = 2;
对于k1和k2,比较器报告它们相等,映射将包含键/值对{k1,2}
用
{k2,2}
替换成对的{k1,1}
最优雅的方法是什么?还是先擦除k1,然后插入k2的唯一方法?我可以找到两种不同的方法,用等效密钥替换映射中的密钥:
又快又脏的方法
只需将一个键与另一个键交换即可,这是UB,但对于大多数std::map
实现来说应该没问题:
std::swap(const_cast<Key&>(map.find(k2)->first), k2);
一项改进是检查此方法是否将键
转换为等效的键
(改进请参见OP)。如果
k1
等于k2
,{k1,2}
应等于{k2,2}
。如果没有,那么您的比较器就坏了(或者不足以处理这种情况)。(您确定要使用std::map
并选择正确的键类型/比较器吗?)。作为替代方案,您是否考虑将pair key+value作为值?@appleapple Yes,映射的行为应该是自动过滤某些KeyType成员(不是全部)的“唯一性”。所以我的平等定义只是基于其中的一些。示例:KeyType有成员jobsdescription
,我只需要一名教师、一名程序员、一名看门人。。。在我的地图中(但他们有可能不同的其他成员,例如,姓氏
)。如果我在地图中添加第二位教师,则旧教师应被覆盖,即使用新人员数据更新密钥。关于比较国,没有任何变化——但姓氏有变化change@PhilLab它不应该是map[job\u type::teacher]=new\u teacher
?@appleapple不在此映射中,因为值类型有所不同。我只是碰巧需要额外的“过滤”,并且正在考虑是否可以用一个简单的地图来实现这一点谢谢演示!UB很难证明,所以我不会使用它
void adjust(const Key& other) const { value = other.value; }