【问题标题】:How to use std::allocator in custom container properly?如何在自定义容器中正确使用 std::allocator?
【发布时间】:2019-07-15 21:24:05
【问题描述】:

我正在尝试开发自己的容器来实现哈希表。主要要求是这个容器必须与 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&lt;std::pair&lt;const Key, T&gt;&gt; 管理节点密钥?我需要分别创建索引和存储之类的东西吗?

探索std::unordered_map 代码太难得到这些答案,这就是为什么我在开发自定义容器时向您询问方向。

【问题讨论】:

    标签: c++ memory-management allocator


    【解决方案1】:

    为了分配除std::allocator_traits&lt;Alloc&gt;::value_type(我们称之为T)以外的另一种类型的对象(我们称之为Node),其中Alloc是可能的自定义分配器类型,您必须rebind allocator 获取Node 类型的分配器:

    using node_alloc_t = std::allocator_traits<Alloc>::rebind_alloc<Node>;
    node_alloc_t node_alloc;
    node_alloc.allocate(size_);
    

    但是如何正确处理密钥呢?我需要为索引创建另一个存储吗?

    您不一定需要为密钥创建单独的存储。您可以将它们存储在节点中。例如,这就是基于树的容器的工作方式。

    而且我的节点类型不包含任何键。

    如果要单独存储密钥,则需要为它们分配存储空间。

    【讨论】:

    • 我使用别名using storage_allocator_ = typename Alloc::template rebind&lt;node_type&gt;::other; 但是如何正确处理密钥?我需要为索引创建另一个存储吗?因为我必须对键应用哈希函数。而且我的节点类型不包含任何键。
    • @powercat 请注意 rebind 成员已被弃用,并在 c++20 中被删除。你应该像我的例子一样使用std::allocator_traits::rebind_alloc
    • @powercat 见编辑
    • 感谢您对 C++20 的关注!好的,那我试试把key存入节点。
    猜你喜欢
    • 2011-01-31
    • 1970-01-01
    • 1970-01-01
    • 2011-12-12
    • 2015-02-28
    • 1970-01-01
    • 2021-07-19
    • 2021-12-17
    • 1970-01-01
    相关资源
    最近更新 更多