我正在尝试开发自己的容器,该容器将实现哈希表。主要要求是此容器必须与STL兼容。现在,我无法了解如何为内部容器需求分配内存和初始化对象。
主要问题是如何管理此类容器的密钥?我是否需要为哈希函数从键生成的索引分配另一个存储空间?然后通过节点存储桶将它们链接到实际存储?
我的容器有模板参数。
template<
class Key, class T, class Hasher = std::hash<Key>,
class KeyEqual = std::equal_to<Key>,
class Alloc = std::allocator<std::pair<const Key, T>>>
class my_hashtable_v1 {
但是随后我使用这样的内部成员类型为我的容器分配节点。
template<class T>
struct ch_node_t : hash_node {
template<class... Args>
ch_node_t(Args&&... args) : value(std::forward<Args>(args)...) {
}
T value;
};
using node_type = ch_node_t<T>;
using storage_allocator_ = typename Alloc::template rebind<node_type>::other;
以这种方式分配节点是否正确?这是来自insert
方法的代码。
auto node = &storage_[slot];
if(!node_traits::is_allocated(*node)) {
new(node) node_type(v.second);
node_traits::link_head(*node);
--freelist_;
}
storage
是指向已分配池的指针。这就是我分配池的方式:
storage_ = storage_allocator_.allocate(size_);
我无法理解的主要事情是如何正确使用std::allocator<std::pair<const Key, T>>
管理节点密钥?我需要分别创建诸如索引和存储之类的东西吗?
探索std::unordered_map
代码很难获得这些答案,这就是为什么我要求您在开发自定义容器中提供指导。
答案 0 :(得分:1)
为了分配除Node
(称为std::allocator_traits<Alloc>::value_type
)以外的另一种类型的对象(我们称为T
),其中Alloc
是可能的自定义分配器类型,您必须rebind
分配器才能获得类型Node
的分配器:
using node_alloc_t = std::allocator_traits<Alloc>::rebind_alloc<Node>;
node_alloc_t node_alloc;
node_alloc.allocate(size_);
但是如何正确处理密钥?我需要为索引创建另一个存储吗?
您不一定需要为密钥创建单独的存储。您可以将它们存储在节点中。例如,这就是基于树的容器的工作方式。
我的节点类型不包含任何键。
如果要单独存储密钥,则确实需要为其分配存储空间。