【问题标题】:C++ fixed-capacity associate containerC++ 固定容量关联容器
【发布时间】:2021-02-18 20:48:22
【问题描述】:

我正在寻找像std::unordered_map 这样不使用任何动态分配的容器。我相信任何具有固定数量的键的关联容器都会出现这种情况,甚至是在编译时必须选择的键。

我不是在寻找 constexpr 或编译时哈希映射,因为我希望能够更新映射中的值。

示例用例:

FixedCapacityMap<std::string_view, int> fruits {
  {"n_apples", 0},
  {"n_pairs", 0}
}

fruits["n_apples"] += 1;
fruits["n_pairs"] += 1;

有谁知道这样的库是否存在,如果没有,如何实现这样的东西?

【问题讨论】:

  • “我不是在寻找 constexpr 或编译时哈希映射,因为我希望能够更新映射中的值。” -- 如果您只想更新值而不是键,那么您可以有一个编译时映射,它将键映射到对实际值的某种引用。这些引用可以是值数组、指针或 C++ 引用的索引。这样,您可以在不实际更改地图的情况下更改值。
  • 在编译时是否知道密钥?另外,我们在谈论多少个键(数量级)?
  • 密钥在编译时是已知的,并在构造函数中提供。我正在寻找通用的东西,适合不同大小的键,但在我的用例中,它可能是 10 到 200 个键。

标签: c++ dictionary associative-array stdmap


【解决方案1】:

“无动态分配”规则的一个必然结果是底层数据嵌入在您的类型中,因此您还需要将键的数量指定为模板参数。

如果在编译时知道键,您可以在其上构造一个固定大小的哈希表。

一般来说,下一个最好的方法是链式哈希或二进制搜索。这是一个在std::array&lt;std::pair&lt;K,V&gt;, N&gt; 上使用二进制搜索的小实现:

template <class K, class V, size_t N>
class FixedCapacityMap {
    public:
        using value_type = std::pair<K,V>;
        FixedCapacityMap(std::initializer_list<value_type> init) {
            assert(init.size() == N);
            std::copy(cbegin(init), cend(init), begin(store));
        }

        V& operator[](const K& key) {
            auto it = std::lower_bound(begin(store), end(store), std::pair{key, V()});
            if (it == end(store) || it.first != key)
                throw std::out_of_range(key);
            return it.second;
        }

    private:
        std::array<value_type, N> store;
}

【讨论】:

  • 哦,这当然行得通!我不知道为什么我认为你不能只对数据进行排序。我确实希望在编译时知道密钥,所以这是可行的。
  • 我刚刚意识到我完全忘记了二进制搜索方面。哇!
【解决方案2】:

我能够找到具有此功能的库:

https://github.com/serge-sans-paille/frozen

它允许constexpr 和constinit 有序和无序映射(我新添加的)能够在运行时更新值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-05
    • 1970-01-01
    • 2011-09-21
    • 2022-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多