固定大小的 std::vector
Posted
技术标签:
【中文标题】固定大小的 std::vector【英文标题】:Fixed size std::vector 【发布时间】:2012-07-04 19:01:06 【问题描述】:我目前正在改变我访问数据结构的方式,并且我正在审查向量向量的一般情况下的两种解决方案之一。
我的动机很简单;我想要缓存局部性而不放弃我的接口。
我知道我的向量在编译时的最大大小,但它们并不总是达到最大值。常见的情况是80%左右,每个向量的总大小要比较小。 如果我达到那个最大值,我在某处的逻辑上犯了错误,并希望它抛出一个错误。
想到的第一个解决方案是使用带有 std::vector 的池分配器,这似乎是个好主意,但可能有点混乱;之前没有正确使用分配器,我不太确定解决方案。我不太喜欢将数据与其所有者分开存储,我希望实现尽可能透明。
目前,第二种解决方案对我来说很有效,但我想让它变得不那么符合要求。目前是这样的:
class Foo
public:
std::array<Bar, 10> bars;
size_t used;
// std::vector<Bar> bars; // reserved to 10... maybe
void add(int var1, int var2)
if (used >= bars.size()) throw "Error";
bars[used] = Bar(var1, var2);
++used;
// std::vector alternative
// bars.push_back(Bar(var1, var2));
void remove(size_t idx)
bars[idx] = bars.back();
--used;
// bars.back().~Bar(); // should happen, not sure if safe
// std::vector alternative
// bars[idx] = bars.back();
// bars.pop_back();
如前所述,效果很好。但是,如果我想将此解决方案移到其他地方,我宁愿不必再次实现它,并且在破坏方面具有适当的语义(类似于 actual 向量的语义)。
那么,我想知道什么是好的解决方案?目前,我已经开始包装std::array
,但它开始变得凌乱,我确信这已经解决了问题。
【问题讨论】:
通过让你的接口采用一个它们无法添加的向量,你破坏了它们。他们首先不应该采用向量,而是采用数组。还是我错过了什么? 目前,我使用的是std::vector
,并保留了必要的空间。关键是他们可以随意添加/删除,但不应永远不要超过最大限制。目前这并没有严格执行,因为它并不重要,它只是我可以利用的东西。
所以我猜“改变你的界面”不是一个理想的解决方案?
@Oli Charlesworth,鉴于当前解决方案之间的切换工作只是从std::vector
更改为std::array
并添加使用的元素数量;我希望不必再做任何事情;但是如果我以后想在其他地方做这件事,这将是一笔巨大的财富;正如我所知道的许多情况下,我知道运行时的最大大小,想要向量的灵活性,但需要数组的局部性(特别是如果封装在一个对象中,在经常迭代的 1000 个对象中,如果分配了缓存,则在其中颠簸无处不在)。
您可以使用decltype
;这是包装模板的明智风格。您对throw
的使用有问题;你肯定可以抛出适当的异常吗?您调用的析构函数 (this->back().~T();
) 错误;您应该将元素保持在有效状态并使用this->back() = T()
重置为默认初始化状态。
【参考方案1】:
请参阅link,了解具有类向量接口的固定大小数据结构的几个选项。特别是,boost::auto_buffer
和 eastl::fixed_vector
对于您的代码来说似乎是可行的选择。
另一种选择是使用 Hinnant 的 stack allocator 和常规的 std::vector
,但是 MSVC++ 在编译它时遇到了一些问题。
【讨论】:
该网站现在已死/存档/受保护。 @J.Hirsch 谢谢,FTFY :) '珍惜它。我上班时无法到达那里;严重过滤的网站真是太痛苦了。【参考方案2】:Boost 有一个用于此目的的 MultiArray 类。
【讨论】:
以上是关于固定大小的 std::vector的主要内容,如果未能解决你的问题,请参考以下文章