1

次のコードはを定義しunordered_setます。コードは問題なくコンパイルされます。ただし、findを呼び出すときにファンクタースローの代わりにラムダ関数を使用します。

libc ++ abi.dylib:例外をスローして終了します

#include <unordered_set>

class pair_hash {
    public:
        size_t operator() (const std::pair<int, int> &x) const {
            return std::hash<int>()(x.first) ^ std::hash<int>()(x.second);
        }
};

int main() {
    std::unordered_set<std::pair<int, int>, pair_hash> temp;
    temp.find(std::make_pair(0,0));


    std::function<std::size_t(std::pair<int , int>)> fpair_hash;
    fpair_hash = [](const std::pair<int, int>& v) -> std::size_t
    {
        return std::hash<int>()(v.first) ^ std::hash<int>()(v.second);
    };

    std::unordered_set<std::pair<int, int>, decltype(fpair_hash)> temp2;
    //why does this not work?
    temp2.find(std::make_pair(0,0));
    return 0;
}

clang ++ -std = c ++ 11 -stdlib = libc ++ -o test test.cpp

4

1 に答える 1

3

decltype(fpair_hash)つまりstd::function<std::size_t(std::pair<int , int>)>、空のハッシュ関数を使用してセットを構築しているだけです。

次のコンストラクターに関数を提供する必要がありますstd::unordered_set

std::unordered_set<std::pair<int, int>, decltype(fpair_hash)> temp2(10, fpair_hash);

これで動作するはずですが、使用std::functionするとポリモーフィック呼び出しのオーバーヘッドが発生するため、おそらく必要ありません。

auto fpair_hash = [](const std::pair<int, int>& v) -> std::size_t
{
    return std::hash<int>()(v.first) ^ std::hash<int>()(v.second);
};

最後に、ハッシュ関数はあまり良くありません-すべてのペア(x, x)をにマップし0ます。おそらく、x * 17 + y * 13代わりにのようなものを使用x ^ yすると、衝突の可能性が低くなります。

于 2013-02-12T21:17:05.140 に答える