【问题标题】:container class for constant data with compile time initialization具有编译时初始化的常量数据的容器类
【发布时间】:2015-10-18 22:36:45
【问题描述】:

我搜索的东西是 std::vector 但没有大的开销并且比 std::array 多一点,因为使用 std::array 我没有存储大小(它只能从类型本身知道) )。

我想要达到的目标:

用“动态”容器写成这样:

std::map< int, std::vector< std::pair<int,int>>>;

我在运行时不需要修改,但在运行时我需要大小信息。用 std::array 替换 std::vector 是行不通的,因为数组必须是所有映射条目的相同大小,这不是我需要的。

只有我!想问是否已经有可用的实现。如果答案只是“否”,则无需建议如何完成这项工作。我只想不再重新发明轮子:-)

背景:我可以在我的小型 avr 控制器上使用 stl,但开销“有点”高。所以我寻找一个有希望的标准实现,它满足编译时间常数表示的需求,并实现了诸如 begin()/end() 和迭代器之类的功能,以满足最低容器要求,以使它们与基于范围的 for 等一起使用。

c++14 也可用,如果我要搜索的话。

我发现的所有内容都是完整的模板实现,其中对数据的访问也是编译时间常量,例如:

container.get<2>() 

我也无法使用,因为我需要运行时变量来访问我的数据。

编辑:使用 std::vector 时会出现哪个问题/开销:

在使用 std::vector 时,我还需要 new/delete,这会导致 avr 具有 malloc/free。我还发现,在 avr 上,向量本身的初始化对于我使用的每个模板实例都需要大约 350 字节的代码。 operator[] 这样的访问函数和迭代器都非常小。

【问题讨论】:

  • std::map&lt;X&gt;没有意义,key类型/值类型是什么?
  • 你在说什么“大开销”?
  • @kennytm:解决了这个问题!谢谢
  • @JonathanPotter:向问题添加一些信息。
  • 你想要const std::map&lt;int, std::initializer_list&lt;std::pair&lt;int, int&gt;&gt;&gt; 吗?

标签: c++ c++14 avr compile-time-constant


【解决方案1】:

为避免std::vector开销,您可以改用std::initializer_list

const std::map<int, std::initializer_list<std::pair<int, int>>>

【讨论】:

  • 你能举个例子如何使用它吗?
  • 我不确定操作是否意识到这并不能避免堆分配,我认为这是他的主要问题。
【解决方案2】:

我并不完全清楚您在寻找什么,但我认为您可以通过以下方式实现您所需要的:

  1. 您不知道每个包含的元素(例如 N 个元素)的确切大小,但您会在程序启动时知道。然后,只要您知道容器的大小,就只保留一个连续的内存块来保存所有容器的所有内部元素。 (一种动态分配)
  2. 使用通过范围构造的向量创建地图:std::vector(start, end),其中开始和结束是通过 N 个元素的块计算的。
  3. 然后填充地图。如果您并不严格需要地图,您还可以计算每个向量的开始和结束位置,然后创建一个初始数组,其中包含每个向量位置的索引...

【讨论】:

  • 我可能问得很不清楚。但动态分配正是我不想要的。我用 map/vector 给出的示例应该替换为可用于编译时分配的某种类型。
【解决方案3】:

您的要求在原则上似乎是不可能的。你说你想避免你的向量类型的堆分配,但是堆栈上的类型的大小必须在编译时知道,并且对于该类型的所有成员都是相同的。由于 map 是同构容器,因此值类型必须是具有恒定大小的单一类型。您可以用元组替换映射,但是在编译时必须知道所有键。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-02
    • 2014-02-18
    • 2021-04-22
    • 1970-01-01
    • 2013-04-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多