std :: unordered_setコンストラクター
-
29-09-2019 - |
質問
私はunordered_setのコンストラクターを見てきました。ハッシュバケツの数を設定せずに、カスタムアロケーターインスタンスを使用してUNORDERED_SETを作成することはできませんか?カスタムアロケーターが必要なので、実装の詳細をめちゃくちゃにしたくないので、このタイプはデフォルト値の定義を提供しません。 MSDNは、コンストラクターに3つの過負荷のようにしか提供されませんが、どれもそれほど便利ではありません。
編集:聖なるがらくた。 STD :: Hashの私のSTL実装は、カスタムアロケータータイプの文字列に特化していません。明示的なtypedefs std :: string :: wstringのみを実行できます。つまり、ランダムな文字列をハッシュしようとしたくないのは理解できますが、カスタムアロケーターを持っているからといって?これは私をうんざりさせます。
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()));
}
};
問題を解決しますが、冗長な構造とコピー? ewwww。
解決
それは奇妙ですが、あなたは正しいです。考えられるのは、デフォルトで可能なすべてのパラメーターの組み合わせをサポートするのはやり過ぎだということだと思います。
これを処理するために考えることができる最善の方法は、空を構築することです 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 */));
他のヒント
あなたが書いているので 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));
もちろん、お気に入りの実装から定数をリッピングすることもできます。