Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ std::map:使用自定义运算符时更新密钥_C++_C++11_Stl_Std_Stdmap - Fatal编程技术网

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; }