【问题标题】:C++11 unordered_set with std::owner_less-like hashingC++11 unordered_set 与 std::owner_less-like 散列
【发布时间】:2015-10-01 09:47:51
【问题描述】:

我正在使用外部网络库,它返回一些代表打开的套接字的魔术结构,文档说当将它们插入 STL 容器时,应该使用 std::owner_less 比较它们。

std::map<MagicStructure, std::shared_ptr<Client>, std::owner_less<MagicStructure>> sockets;

但是我想改用unordered_map。我该怎么做? std::owner_less 是一个比较器,它对哈希映射毫无用处。挖掘源代码,MagicStructure 似乎是std::shared_ptr 的类型定义。

【问题讨论】:

  • 这可能是标准的真正遗漏。我们需要像owner_equalowner_hash 这样的东西;后者可以是控制块地址的哈希值。
  • 你可以查看源代码,看看他们是否设置了删除器,如果设置了,是什么类型。然后尝试get_deleter。可能deleter 可以用作“所有者”的代理。

标签: c++ c++11 stl shared-ptr unordered-map


【解决方案1】:

std::owner_less 的排序可以很容易地适应相等比较(如果 a 和 b 都不在另一个之前,则 a 和 b 相等)。

std::shared_ptr 的默认散列实现(散列get() 的结果)应该足够了。 如果不能保证指向同一对象的两个指针从 @ 返回相同的值,则不会987654324@,在这种特殊情况下,这通常是可能的并且是合理的。

【讨论】:

  • 散列函数似乎与owner_less 所暗示的相等性不兼容,因为散列被明确给出为get() 的散列!
【解决方案2】:

不幸的是,您似乎必须使用map,而不能在这种情况下使用unordered_maphttp://wg21.cmeerw.net/lwg/issue1406

对基于所有权的等价关系的哈希支持不能 由任何用户定义的方式提供,因为有关信息 所有权共享对用户根本不可用。因此, 提供基于所有权的哈希支持的唯一方法是提供它 被标准库侵入。

换句话说,在shared_ptr: http://www.cplusplus.com/reference/memory/shared_ptr/get/ 中存储了(由get() 返回)和拥有的指针(当引用计数达到0 时删除)。要在unordered_map 中使用自有指针,您需要基于自有指针的hash()equals() 操作。但它们在 STL 中没有提供。而且您无法自己实现它们(无需重新实现 shared_ptr 并更改您的 MagicStructure 的定义),因为 shared_ptr 没有公开拥有的指针。

【讨论】:

  • en.cppreference.com/w/cpp/memory/shared_ptr/owner_before 是相关的,因为它更清楚地说明了a.get() &lt; b.get()a.owner_before(b) 的不同之处。讨论两个共享指针如何拥有不同的.get() 但拥有不同的所有者(“上帝模式”shared_ptr 构造函数)也可能有用。
猜你喜欢
  • 2012-11-21
  • 2016-02-21
  • 2015-12-03
  • 1970-01-01
  • 1970-01-01
  • 2013-03-20
  • 2023-03-23
  • 1970-01-01
  • 2015-10-22
相关资源
最近更新 更多