在std::unordered_map中使用对象引用作为键

12

我想知道在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;
当尝试编译这个简单的代码片段时,我遇到了一些关于方法重定义的错误:
在使用具有libc++的clang的情况下:
/usr/include/c++/v1/unordered_map:352:12: 错误:class member cannot be redeclared
size_t operator()(const _Cp& __x) const
在使用具有libstdc++的gcc 4.6的情况下:
/usr/include/c++/4.6/bits/hashtable_policy.h:556:5: 错误:
‘std::__detail::_Map_base<_Key, _Pair, std::_Select1st<_Pair>, true,_Hashtable>::mapped_type& std::__detail::_Map_base<_Key, _Pair,std::_Select1st<_Pair>, true, _Hashtable>::operator [with_Key = Object&, _Pair = std::pair, _Hashtable =std::_Hashtable,std::allocator >,std::_Select1st >, std::equal_to,object_hash, std::__detail::_Mod_range_hashing,std::__detail::_Default_ranged_hash,std::__detail::_Prime_rehash_policy, false, false, true>,std::__detail::_Map_base<_Key, _Pair, std::_Select1st<_Pair>, true,_Hashtable>::mapped_type = int]’ cannot be overloaded
/usr/include/c++/4.6/bits/hashtable_policy.h:537:5: 错误:
‘std::__detail::_Map_base<_Key, _Pair, std::_Select1st<_Pair>, true,_Hashtable>::mapped_type& std::__detail::_Map_base<_Key, _Pair,std::_Select1st<_Pair>, true, _Hashtable>::operator[](const _Key&) [with_Key = Object&, _Pair = std::pair, _Hashtable =std::_Hashtable,std::allocator >,std::_Select1st >, std::equal_to,object_hash, std::__detail::_Mod_range_hashing,std::__detail::_Default_ranged_hash,std::__detail::_Prime_rehash_policy, false, false, true>,std::__detail::_Map_base<_Key, _Pair, std::_Select1st<_Pair>, true,_Hashtable>::mapped_type = int]’与
此问题是否是新标准强制实施的某些限制?如果是,为什么?
有没有一种方法可以绕过这个限制?
如果我使用旧的gnu hash_map (__gnu_cxx::hash_map),我就不会有这个问题。
2个回答

16
新标准定义了std:reference_wrapper<T>来解决这个限制。它可以隐式转换为T&,使其透明,并像引用一样保证没有null状态,但与引用不同的是它可以被重新设置。更多信息请参见在使用std::map中将std::reference_wrapper作为键

0

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

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 的构造函数: template< class T > struct hash<T*>;


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接