保证 std::unordered_multimap 中的键唯一性

Posted

技术标签:

【中文标题】保证 std::unordered_multimap 中的键唯一性【英文标题】:Guarantees about key uniqueness in std::unordered_multimap 【发布时间】:2016-06-09 14:52:10 【问题描述】:

在处理迭代时,我想知道 std::unordered_multimap 内的关键对象的唯一性。

我会尝试解释一下:我需要将一些数据与映射中的键类型相关联,这些数据不应该在HashKeyEqual元素中考虑,但我需要它来避免存储单独的地图(用于优化目的)。

所以与我的想法相关的代码如下:

struct Key 
  void* data;
  mutable bool attribute;

  Key(void* data) : data(data), attribute(false)  
  bool operator==(const Key& other) const 
    return data == other.data;
  
;

struct KeyHash 
  size_t operator()(const Key& key) const 
    return std::hash<void*>()(key.data);
  
;

class Foo 
public:
  int i;
  Foo(int i) : i(i)  
;

std::unordered_multimap<Key, Foo, KeyHash> map;

问题源于这样一个事实,尽管这可以正常工作,但不能保证作为std::pair&lt;const Key, Foo&gt; 映射到单个元素的第一个元素检索到的键始终相同。作为const Keypair,听起来地图中的每个元素都有其键值的副本,所以如果我这样做了

void* target = new int();
map.emplace(std::make_pair(target, Foo(1)));
map.emplace(std::make_pair(target, Foo(2)));


auto pit = map.equal_range(target);
pit.first->first.attribute = true;  
std::cout << std::boolalpha << (++pit.first)->first.attribute << endl;

这会产生false,这证实了我的想法。因此,如果您有多个具有相同键的值(这是您想要的,因为您使用的是std::unordered_map),确实会浪费大量空间来存储键。

我没有看到任何其他解决方案,而不是类似的东西

struct Value

  std::vector<Foo> foos;
  bool attribute;
;

std::unordered_map<void*, Value> map;

这允许我将属性与键配对,但由于需要使用两个级别的迭代器,所以一切都变得不那么干净了。

还有其他我没有看到的解决方案吗?

【问题讨论】:

只要使用boost::multiindex map[target] = Foo(1); std::unordered_multimap 不会超载 operator[] 不太清楚您的要求是什么。您是否正在寻找类似std::unordered_map&lt;Key, std::vector&lt;Foo&gt;&gt; 的东西?这会很高兴地将多个值与同一个键关联,而不会复制键。 为什么不std::unordered_map&lt;Key, std::vector&lt;Foo&gt;&gt; ?相同的密钥将只存储一次。只是您的插入操作首先需要获取对该向量的引用并附加到它。 @IgorTandetnik 我的要求是为每个键存储一次配对的附加数据,而不必将其存储在单独的 std::unordered_map 中,但它看起来不像多映射。 【参考方案1】:

23.5.5.1 类模板 unordered_multimap 概述 [unord.multimap.overview]

1 unordered_multimap 是一个无序关联容器,它支持等效键( unordered_multimap 可能包含每个键值的多个副本)并且关联另一个值 使用键键入 mapped_type。 unordered_multimap 类支持前向迭代器。

unordered_multimap 可能包含多个密钥副本,如果您想要一个密钥副本,那么unordered_map&lt;K, vector&lt;V&gt;&gt; 可能更合适。

【讨论】:

以上是关于保证 std::unordered_multimap 中的键唯一性的主要内容,如果未能解决你的问题,请参考以下文章

架构设计消息篇之保证消息顺序性

聊聊 Kafka:Kafka 如何保证一致性

RabbitMQ 如何保证消息顺序 --- 2022-04-03

Redis如何保证原子性

Java中如何保证线程安全性

2020-12-25:MQ中,如何保证消息的顺序性?