【问题标题】:Using an object reference as a key in std::unordered_map在 std::unordered_map 中使用对象引用作为键
【发布时间】:2012-05-22 14:13:15
【问题描述】:

我想知道是否可以在 C++ 的 unordered_map 容器中使用对象引用作为键。

#include <unordered_map>

class Object {
    int value;
};

struct object_hash {
  inline size_t operator()(const Object& o) const { return 0; }
};

std::unordered_map<Object&, int, object_hash> map;

在尝试编译这个简单的 sn-p 时,我遇到了一些关于方法重新定义的错误:

在 libc++ 中使用 clang

/usr/include/c++/v1/unordered_map:352:12:错误:无法重新声明类成员

size_t operator()(const _Cp& __x) const

将 gcc 4.6 与 libstdc++ 一起使用

/usr/include/c++/4.6/bits/hashtable_policy.h:556:5: 错误: 'std::__detail::_Map_base<_key _pair std::_select1st>, true, _Hashtable>::mapped_type& std::__detail::_Map_base<_key _pair std::_select1st>, true, _Hashtable>::operator [with _Key = 对象&,_Pair = std::pair,_Hashtable = std::_Hashtable, 标准::分配器 >, std::_Select1st >, std::equal_to, object_hash, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy,假,假,真>, std::__detail::_Map_base<_key _pair std::_select1st>, true, _Hashtable>::mapped_type = int]' 不能重载

/usr/include/c++/4.6/bits/hashtable_policy.h:537:5:错误:with 'std::__detail::_Map_base<_key _pair std::_select1st>, true, _Hashtable>::mapped_type& std::__detail::_Map_base<_key _pair std::_select1st>, true, _Hashtable>::operator[](const _Key&) [与 _Key = Object&,_Pair = std::pair,_Hashtable = std::_Hashtable, 标准::分配器 >, std::_Select1st >, std::equal_to, object_hash, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy,假,假,真>, std::__detail::_Map_base<_key _pair std::_select1st>, true, _Hashtable>::mapped_type = int]'

如果我改用旧的 gnu hash_map (__gnu_cxx::hash_map),我就没有这个问题。

这是新标准施加的一些限制吗?如果有,为什么?

有没有办法解决这个限制?

【问题讨论】:

    标签: c++ c++11 libstdc++ libc++


    【解决方案1】:

    新标准定义了std:reference_wrapper&lt;T&gt; 来解决这个限制。

    它可以隐式转换为T&amp;,因此它是透明的,并且类似引用保证没有null 状态,但与引用不同,它可以重新就位。

    Using std::reference_wrapper as key in std::map 中的更多信息。

    【讨论】:

      【解决方案2】:

      我遇到了这个问题,我的同事帮我找到了一个我认为值得分享的解决方案:

      struct RefWapperAddressHash
      {
          std::size_t operator()( Object const& obj ) const
          {
              std::hash< Object const* > theHash{};
              return theHash( &obj );
          }
      };
      
      std::unordered_map< std::reference_wrapper< Object >, int, RefWrapperAddressHash > m_map;
      

      这使用 std::hash's ctor : template&lt; class T &gt; struct hash&lt;T*&gt;;

      【讨论】:

        猜你喜欢
        • 2012-07-09
        • 2018-07-09
        • 2020-03-09
        • 1970-01-01
        • 2017-04-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多