4

これによると、次のようにTR1unordered_mapで等式関数を定義することができます。

#include <tr1/unordered_map>
using namespace std;
using namespace std::tr1;
struct foo{
    ...
    bool operator==(const foo& b) const{
        return ..;
    }
};

unordered_map<foo,int> map;

同じようにハッシュ関数を定義することは可能ですか?

4

2 に答える 2

12

デフォルトのハッシュを変更したい場合(または、より頻繁に、現在サポートされていないタイプのハッシュを提供したい場合)、std::tr1::hash<T>キータイプの特殊化を提供します。

namespace std { 
namespace tr1 { 
    template<>
    struct hash<typename my_key_type> {
        std::size_t operator()(my_key_type const &key) {
            return whatever;
        }
    };
}
}

ユーザー定義型用に既存のテンプレートを特殊化することは、でコードを書くことが特に許可されているまれなケース1つであることに注意してください。namespace std

于 2011-03-25T15:47:19.267 に答える
1

unordered_mapクラスのシグネチャは次のとおりです。

template<class Key,
    class Ty,
    class Hash = std::hash<Key>,
    class Pred = std::equal_to<Key>,
    class Alloc = std::allocator<std::pair<const Key, Ty> > >
    class unordered_map;

デフォルトのPred、std :: equal_to <>は、デフォルトでoperator ==を使用して等しいかどうかをチェックするため、この例は機能します。コンパイラはfoo::operator ==メンバー関数を見つけて、それを使用します。

std :: hashには、クラスのメンバー関数を呼び出す特殊化がないため、カスタムハッシュを使用してfooにメンバーを追加することはできません。代わりに、std::hashを特殊化する必要があります。fooのメンバー関数を呼び出す場合は、先に進んでください。最終的には次のようになります。

struct foo
{
    size_t hash() const
    {
       // hashing method here, return a size_t
    }
};

namespace std
{
    // Specialise std::hash for foo.
    template<>
    class hash< foo >
        : public unary_function< foo, size_t >
    {
    public:
        size_t operator()( const foo& f )
        {
            return f.hash();
        }
    };
}
于 2011-03-25T15:50:42.013 に答える