3

クラスがあるとしますX

class X {
    // ...
    size_t hash() const { return ...; }
};

としてstd::tr1::unordered_map<X, int, HashFn>渡したい場所を 作成したいと思います。独自のファンクター オブジェクトを宣言できることはわかっています。へのポインタを直接渡すことでこれを行う方法があるはずだと思います。X::hash()HashFnX::hash()

ある?

4

4 に答える 4

2

いいえ; あなたがそれを示したように、あなたは小さなユーティリティ構造体を必要とします:

#include <functional>

template<typename T, std::size_t (T::*HashFunc)() const = &T::hash>
struct hasher : std::unary_function<T, std::size_t>
{
    std::size_t operator ()(T const& t) const
    {
        return (t.*HashFunc)();
    }
};

unordered_map次に、次のように作成できます。

std::tr1::unordered_map<X, int, hasher<X> > m;
于 2011-04-11T14:50:14.347 に答える
2

いいえ、ありません。その理由は、HashFn として使用されるものはすべて、コンテナー内のオブジェクトへの const 参照である単一の引数を取る必要があるためです。 コンテナー内のオブジェクトへのconstポインターX::hashである単一の引数を取るため(この場合、ポインターは暗黙的な最初の引数です)、その関数を単独で使用することはできません。this

おそらく、boost::lambda と boost::bind を使用してバインド マジックを使用します。正確な方法はわかりませんが、おそらく次のようになります。

boost::bind(&X::hash, &_1);

X::hash をポインターで呼び出す関数オブジェクトを作成します。

于 2011-04-11T14:43:15.937 に答える
0
size_t hash() const { return ...;}

ハッシュ値を計算Keyする関数は、関数がとらない型のパラメーターを 1 つ受け取ります。したがって、その署名はそもそも間違っています。

ファンクターではなく関数を実装したいので、次のようにします。

size_t hash(const KeyType &key) 
{
    return /*calculate hash and return it*/;
}

それをstaticメンバー関数にして渡すX::hashか、フリー関数にするかはあなたの選択です。

于 2011-04-11T14:43:21.650 に答える
0

直接はできませんが、ラップすることはできます。これを行う簡単な方法はboost::mem_fn()、またはコンパイラがサポートしている場合は標準の同等物を使用することです: tr1::mem_fn()(TR1 から) またはstd::mem_fn()(C++11 から)。

編集:実際にはそれほど単純ではありません。mem_fn()関数パラメーターに対しては問題なく機能しますが、戻り値の型が指定されていないため、テンプレート パラメーターとして使用するのは困難です。C++11 をサポートしている場合はdecltype、型を見つけるために使用できます。それ以外の場合は、あなたが述べたように、独自の関数オブジェクトを作成することをお勧めします。

于 2011-04-11T14:44:20.010 に答える