【问题标题】:std::map : update key when using custom operatorstd::map :使用自定义运算符时更新键
【发布时间】:2017-08-20 03:13:44
【问题描述】:

当为std::map<KeyType,ValueType,Comparator> 使用自定义运算符时,它在设计上只比较我的一些KeyType 字段,两个对象KeyType k1, k2 可能包含不同的数据,但对于地图它们看起来像同一个键。毕竟,这就是我们首先编写自定义 Comparator 的原因。

所以如果我写

map[k1] = 1;
map[k2] = 2;

如果 k1 和 k2 比较器报告它们相等,则映射将包含键/值对 {k1, 2}

{k1, 1}替换为{k2, 2}最优雅的方法是什么,或者是先擦除k1然后插入k2的唯一方法?

【问题讨论】:

  • 如果k1 等于k2{k1, 2} 应该等于{k2, 2}。如果不是,则您的比较器已损坏(或对于这种情况还不够)。 (您确定要std::map 并选择正确的键类型/比较器吗?)
  • 我认为没有比你想象的更好的方法来替换这对了。作为替代方案,您是否认为将 key+value 作为值?
  • @appleapple 是的,地图应该以这种方式自动过滤某些 KeyType 成员(不是全部)的“唯一性”。所以我的平等定义仅基于其中一些。示例:KeyType 有成员 jobDescription,我只想要我的地图中的一名教师、一名程序员、一名看门人......(但他们还有其他可能不同的成员,例如 surname)。如果我在地图上添加第二位老师,则应该覆盖旧的老师,即使用新人员数据更新的密钥。关于比较器,没有任何变化 - 但姓氏确实发生了变化
  • @PhilLab 不应该是map[job_type::teacher]=new_teacher
  • @appleapple 不在此映射中,因为值类型不同。我只是碰巧需要额外的“过滤”,并且正在考虑是否可以通过简单的地图来实现这一点

标签: c++ c++11 stl std stdmap


【解决方案1】:

我可以找到两种不同的方法来用 等效 键替换地图中的键:

快速而肮脏的方法

只是swap 一个键和另一个键,它 UB,但大多数std::map 实现应该没问题:

std::swap(const_cast<Key&>(map.find(k2)->first), k2);

Demo.

不那么快速和不那么脏的方法

提供一个调整const方法Key来改变它的内部状态:

void adjust(const Key& other) const { value = other.value; }

检查此方法是否将Key 转换为等效的Key 是一项改进。

Demo(对 OP 的改进)。

【讨论】:

  • 感谢演示! UB很难证明,所以我不会用它
猜你喜欢
  • 1970-01-01
  • 2023-03-21
  • 2011-07-10
  • 2012-01-12
  • 2014-07-15
  • 1970-01-01
  • 2023-03-21
  • 2017-02-18
  • 2011-04-12
相关资源
最近更新 更多