2010-12-01 97 views
2

我一直在寻找unordered_set的构造函数。是不是可以使用自定义分配器实例构建unordered_set而不设置散列桶的数量?我真的宁愿不要混淆实现细节,因为我想要一个自定义分配器,而类型不提供默认值的定义。 MSDN只为构造函数提供了三个重载,其中没有一个非常有用。std :: unordered_set构造函数

编辑:圣洁的废话。 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

关于你的编辑:是的,很害怕。 `std :: hash`有点缺乏,特别是我认为标准应该提供一个函数来散列一个字节序列,以使它更容易专门用于UDT(包括带有自定义分配器的字符串)。但是,由于你的交替分配的字符串与任何授权的“散列”专业化无关,你是SOOL,看不到任何帮助。 AFAIK你只需选择你自己的散列算法,然后写一个专门化,或者指定散列到你的容器。 – 2010-12-01 17:32:24

+0

@Steve:不完全。 basic_string构造函数可以使用任何迭代器,因此将它扩展为allocator不可知的实际并不是非常困难,但它涉及冗余副本,这使我RAEG成为可能。 – Puppy 2010-12-01 17:34:22

+0

@DeadMG:是的,这取决于你为什么使用自定义分配器。如果你希望程序中的所有分配都通过你的分配器,那么它不仅仅是一个冗余副本,而是完全失败。 – 2010-12-01 17:36:27

回答

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

既然你正在写的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)); 

你也可以,当然,只是淘汰定了你最喜欢的实现。

相关问题