2

我一直在研究 unordered_set 的构造函数。在不设置哈希桶数量的情况下,是否无法使用自定义分配器实例构造 unordered_set?我真的不想弄乱实现细节,因为我想要一个自定义分配器,并且该类型没有为默认值提供任何定义。MSDN 只为构造函数提供了三个重载,没有一个非常有用。

编辑:神圣的废话。我的std::hash 的STL 实现不会专门用于具有自定义分配器类型的字符串——它只能执行显式类型定义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()));
    }
};

解决了问题,但重复建设和复制?呜呜呜。

4

2 回答 2

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 */));
于 2010-12-01T16:46:08.400 回答
0

由于您正在编写Allocator,因此控制存储桶的数量也很有意义,毕竟两者都与内存相关:)

如果你不想,Steve 给出了方法的核心,现在让我提出一个辅助函数 :)

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));

当然,您也可以简单地从您最喜欢的实现中删除常量。

于 2010-12-01T17:43:14.707 回答