固定大小的 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-&gt;back().~T();) 错误;您应该将元素保持在有效状态并使用this-&gt;back() = T() 重置为默认初始化状态。 【参考方案1】:

请参阅link,了解具有类向量接口的固定大小数据结构的几个选项。特别是,boost::auto_buffereastl::fixed_vector 对于您的代码来说似乎是可行的选择。

另一种选择是使用 Hinnant 的 stack allocator 和常规的 std::vector,但是 MSVC++ 在编译它时遇到了一些问题。

【讨论】:

该网站现在已死/存档/受保护。 @J.Hirsch 谢谢,FTFY :) '珍惜它。我上班时无法到达那里;严重过滤的网站真是太痛苦了。【参考方案2】:

Boost 有一个用于此目的的 MultiArray 类。

【讨论】:

以上是关于固定大小的 std::vector的主要内容,如果未能解决你的问题,请参考以下文章

C++:固定但运行时定义长度数组的向量

c++新特性11 stdarray

变长 std::array 像

在运行时设置向量向量的大小

Nurbs曲线(2D)固定长度参数化

std::dynarray 与 std::vector