2010-12-01 27 views
2

私はunordered_setのコンストラクタを見てきました。ハッシュバケットの数を設定せずにカスタムアロケータインスタンスでunordered_setを構築することはできませんか?カスタムアロケータが必要なので実装の詳細を混乱させるのではなく、その型はデフォルト値の定義を提供しません。 MSDNはコンストラクタのために3つのオーバーロードしか与えませんが、どれも非常に便利です。std :: unordered_setコンストラクタ

編集:Holy Crap。 std :: hashのSTL実装はカスタムアロケータ型の文字列に特化しません。std :: stringとstd :: wstringの明示的なtypedefsしか実行できません。つまり、ランダムな文字列をハッシュしようとするのではなく、カスタムアロケータがあるからといって理解できますか?これは私を嫌にする。

tokens(std::unordered_set<string>().bucket_count(), std::hash<string>(), std::equal_to<string>(), stl_wrapper::hash_set<string>::allocator_type(this)) 
template<typename Char, typename CharTraits, typename Allocator> class std::hash<std::basic_string<Char, CharTraits, Allocator>> 
    : public std::unary_function<std::basic_string<Char, CharTraits, Allocator>, std::size_t> { 
public: 
    size_t operator()(const std::basic_string<Char, CharTraits, Allocator>& ref) const { 
     return std::hash<std::basic_string<Char, CharTraits>>()(std::basic_string<Char, CharTraits>(ref.begin(), ref.end())); 
    } 
}; 

問題は解決しますが、冗長な構成とコピーはありますか? Ewwwww。

+0

あなたの編集に関して:yup、恐れるほど。 'std :: hash'は少し欠けています。特に、標準では、UDT(カスタムアロケータであなたの文字列を含む)をより簡単にするために、バイトシーケンスをハッシュする関数を標準で提供する必要があります。しかし、交互に割り当てられた文字列は、強制された 'ハッシュ'特殊化のいずれにも関連していないので、あなたはSOOLであり、助けにはなりません。 AFAIKを使用するには、独自のハッシュアルゴリズムを選択してから、特殊化を作成するか、コンテナにハッシュを指定するだけです。 –

+0

@スティーブ:まあまあです。 basic_stringコンストラクタは反復子をとることができるので、実際にはアロケータに依存しないように拡張することは非常に困難ではありませんでしたが、冗長コピーが必要なため、RAEGになりました。 – Puppy

+0

@DeadMG:なぜ、あなたがカスタムアロケータを使用しているのかによる。あなたのプログラムの* all *割り当てがあなたのアロケータを通過するようにしたいのであれば、それは単なる冗長コピーではなく、完全に失敗します。 –

答えて

2

これは奇妙ですが、あなたは正しいです。考えられるのは、可能なすべてのパラメータの組み合わせをサポートするのは過度だと思っていたと思います。

これを処理するには、空のunordered_setをすべてデフォルト設定にして、unordered_set::bucket_countを使用してデフォルトバケットカウントを取得し、実際に必要なコンテナをインスタンス化するときに入力として使用することです。

unordered_set<int> temp; 
size_t buckets = temp.bucket_count; 
unordered_set<string> actual(buckets, Hash(), Pred(), 
    YourAllocator(param1 /*, etc */)); 
+0

私のカスタムアロケータがデフォルト構築できない場合、私はそれを行うことはできません。 – Puppy

+0

編集作業ごとにコードを作成しないのはなぜですか? –

+0

@Steve:YourAllocator()はデフォルトのコンストラクタがないため、コンパイルエラーです。 – Puppy

0

あなたがAllocatorを書いているので、それはすべての両方がメモリに関連した後に、あまりにもバケットの数を制御することは理にかなって:)

したくない場合はスティーブはメソッドの心を与えました今私は、ヘルパー関数を提案してみましょう:)

template <typename T> 
size_t number_buckets() 
{ 
    std::unordered_set<T> useless; 
    return useless.bucket_count(); 
} 

そして、その、少し(シンプル)ヘルパーと:

template <typename T, typename Hash, typename Pred, typename Allocator> 
std::unordered_set<T,Hash,Pred,Allocator> 
    make_unordered_set(Hash const& hash, Pred const& pred, Allocator const& alloc) 
{ 
    static size_t const nbBuckets = number_buckets<T>(); 
    return std::unordered_set<T,Hash,Pred,Allocator>(nbBuckets, hash, pred, alloc); 
} 

autoでかなりよく作品:

auto set = make_unordered_set<std::string>(Hash(), Pred(), Allocator(1,2,3)); 

あなたはまた、もちろん、単にあなたの好きな実装のうち、定数をリッピングすることができます。

+0

いいえ、どのくらいのメモリが割り当てられているかどうかを制御し、問題のアルゴリズムの実装の詳細を制御するので、両方を制御するのは意味がありません。 2つは必ずしも必ずしも関連していません。 – Puppy

関連する問題