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: エラー: クラス メンバーを再宣言できません

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]'はオーバーロードできません

/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]'</p>

代わりに古い gnu hash_map (__gnu_cxx::hash_map) を使用すると、この問題は発生しません。

これは新しい標準によって課せられた何らかの制限ですか? もしそうなら、それはなぜですか?

この制限を回避する方法はありますか?

4

2 に答える 2

16

新しい標準ではstd:reference_wrapper<T>、この制限を回避するように定義されています。

これは暗黙的に a に変換できるT&ため、透過的であり、同様の参照は状態がないことを保証しますがnull、参照とは異なり、再配置できます。

詳細については、キー入力として使用するをstd::reference_wrapperstd::map参照してください。

于 2012-05-22T15:26:31.003 に答える