22

STL 実装がカスタム型を取得できるようにするにはどうすればよいですか? MSVC には class がありstd::tr1::hash、これを使用して部分的に特化できます

namespace std 
{
    namespace tr1 
    { 
        template <> 
        struct hash<MyType> 
        { ... };
    } 
}

しかし、これは推奨される方法ですか?さらに、これは GCC の実装でも機能しますか? についてboost::hashは、無料の関数を提供するだけで十分size_t hash_value (const MyType&)ですが、TR1 の実装に似たようなものはありますか?

4

4 に答える 4

21

私は順序付けられていない連想コンテナ(OPが求めていたようにGCCも使用)でこれを行うための正確な構文を考え出そうとしていましたが、この質問に答えました。

残念ながら、私が望んでいた詳細レベルには達しませんでした。標準ハッシュ関数がどのように実装されているかを gcc ヘッダーに目を通すことで、機能するようになりました。ウェブ上の例が不足していることを考慮して(少なくとも執筆時点では)、これは自分の例を投稿するのに最適な場所だと思いました(GCCで動作することを確認できます):


namespace std { namespace tr1
{
   template <>
   struct hash<MyType> : public unary_function<MyType, size_t>
   {
       size_t operator()(const MyType& v) const
       {
           return /* my hash algorithm */;
       }
   };
}}

(ここには2 つの名前空間があることに注意してください。これは、ネストされた名前空間を折りたたむための私の規則です)

于 2009-04-05T14:27:55.167 に答える
4

はい、これは GCC でも機能します。より大きなプロジェクトで使用していますが、問題なく動作します。TR1 コンテナーに独自のカスタム ハッシュ クラスを提供することもできますが、std::tr1::hash<> が既定のハッシュ クラスであることが指定されています。カスタム型に特化することは、標準のハッシュ機能を拡張する自然な方法のようです。

于 2009-03-15T15:24:17.347 に答える
3

stdライブラリの名前空間に追加するのではなく、特殊化を提供するだけなので、まったく問題ありません。

より一般的なハッシュ アプローチ (たとえば、一般的なタプルのハッシュ) を提供する場合は、Boost Fusion を参照してください。これは簡単な例で、ほとんどのケースで機能します (おそらくタプルのタプルを除いて)

于 2009-03-15T15:44:36.923 に答える
0

次のコード スニペットはstd::tr1::unordered_map、マッピング boost::const_string<char>をハッシュ化void*する方法と同様に特殊化する方法を示しています。std::string

#include <boost/const_string/const_string.hpp>    
typedef class boost::const_string<char> csc;

namespace std
{
namespace tr1
{
template <>
struct hash<csc> {
public:
    size_t operator()(const csc & x) const {
        return std::_Hash_impl::hash(x.data(), x.size());
    }
};
}
}

typedef std::tr1::unordered_map<csc, void*> Map;
typedef Map::value_type Dual; ///< Element Type.
于 2011-05-05T14:59:24.907 に答える