我一直在关注unordered_set的构造函数。是否无法使用自定义分配器实例构造unordered_set而不设置散列桶的数量?我真的不想搞砸实现细节因为我想要一个自定义分配器,并且该类型没有提供默认值的定义。 MSDN只为构造函数提供了三个重载,其中没有一个是非常有用的。
编辑:神圣的废话。我的std :: hash的STL实现不会专门用于具有自定义分配器类型的字符串 - 它只能执行显式typedefs std :: string和std :: 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()));
}
};
解决问题,但多余的构造和复制? Ewwwww。
答案 0 :(得分: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 */));
答案 1 :(得分: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));
当然,您也可以简单地从常用的实现中删除常量。