2017-11-20 14 views
2

std::unordered_mapのキーとしてstd::pairを使用することができます。私の場合は、std::type_indexをペアで使用する必要があります。しかし、それを構築するいくつかの問題があります。私のコードは次のとおりです。ここでは、構文と間違っている何ペアをキーにしてunordered_mapのビルドが失敗する(C++)

/usr/include/c++/7/bits/hashtable_policy.h:87: error: no match for call to ‘(const Multimethod2<Shape, bool, true>::ArgsHash) (const std::pair<std::type_index, std::type_index>&)’ 
    noexcept(declval<const _Hash&>()(declval<const _Key&>()))> 
      ~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~ 

/usr/include/c++/7/bits/hashtable_policy.h:87: error: binding reference of type ‘Multimethod2<Shape, bool, true>::Args& {aka std::pair<std::type_index, std::type_index>&}’ to ‘const std::pair<std::type_index, std::type_index>’ discards qualifiers 
    noexcept(declval<const _Hash&>()(declval<const _Key&>()))> 
      ~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~ 

/usr/include/c++/7/type_traits:154: error: ‘value’ is not a member of ‘std::__and_<std::__is_fast_hash<Multimethod2<Shape, bool, true>::ArgsHash>, std::__detail::__is_noexcept_hash<std::pair<std::type_index, std::type_index>, Multimethod2<Shape, bool, true>::ArgsHash> >’ 
    : public integral_constant<bool, !_Pp::value> 
             ^~~~ 

... 

template<class Base, class Result, bool Commutative> 
struct Multimethod2 
{ 
    using Args = std::pair<std::type_index, std::type_index>; 
    using Method = std::function<bool(Base *, Base *)>; 

    struct ArgsHash { 
     std::size_t operator() (Args &p) const { 
      std::size_t h1 = std::hash<std::type_index>()(p.first); 
      std::size_t h2 = std::hash<std::type_index>()(p.second); 
      return h1^h2; 
     } 
    }; 

    struct KeyEqual 
    { 
     bool operator()(const Args &a1, const Args &a2) const 
     { 
      return (a1.first == a2.first && a1.second == a2.second) || 
        (a1.first == a2.second && a1.second == a2.first); 
     } 
    }; 

    std::unordered_map<Args, Method, ArgsHash, KeyEqual> methods; 
... 
} 

はエラーをお持ちですか?ありがとう!

+3

ArgsHash ::演算子は()constは& –

+0

@MassimilianoJanesでArgsのを取る必要があります...既製多かれ少なかれ汎用ソリューションをboost.hash_combineする試みを与えたいと思うかもしれする必要があること答え、コメントではありません。 – Angew

+0

@MassimilianoJanes、はい、間違ってそれをクリアしました、ありがとう! –

答えて

3

ArgsHash::operator()は、Argsconst&とする必要があります。ところで

は、あなたのハッシュ関数は、(あなたは二つの同一type_indexを持っているときに何が起こるか?)、おそらく悪いハッシュを組み合わせる

は(何のstd :: hash_combineありません理由があります)簡単ではありません。とにかく、あなたは

+0

これは間違っているわけではありません。同じオブジェクトを異なる方法でハッシュしません。多くの不必要な衝突を引き起こすという点ではかなり非効率的ですが、それは「間違っている」よりも「悪い」ものです。 – Angew

+0

@Angew、ok、しかし、標準では、そのようなハッシュでは満たされない複雑さの保証が与えられています。私にとっては、それは「悪い」よりも「間違って」聞こえる。 –

+0

標準ではハッシュが完璧であるとは思っていません。これにより複雑さの保証がより厳密になることはありますか? – Angew

関連する問題