C ++:std :: vector,为两端预留空间
只是有些想法:
我想从大小为n> x的std :: vector的开头擦除x元素。 由于矢量在内部使用数组,因此可以简单地将vector.begin()的指针设置为保留的第一个元素的索引。 但相反,擦除会将数组中的所有元素都移动到第一个元素实际从索引0开始,这使得擦除操作所花费的时间比它可能多得多。
此外,如果内部数组的有效'区域'仅由向量结构的一些开始和结束索引/指针来控制,那么也可以选择在第一个元素前面保留空间。 例如,一个矢量被初始化,并在结尾处保留20个空格,在开始处保留10个空格。 在内部,创建一个空间数组30(或32),其中起始索引/指针指向内部数组的第11个值,允许以恒定速度将新元素包括到“向量”的前面。
那么,我的观点是,我认为这样的数据结构会有所帮助,至少对我而言是这样。 我很确定有人已经想到了这一点,并已经实施了。 所以我想问一下:我描述的数据结构如何调用? 如果存在,我很乐意使用它。 我认为这不是一个双链表,因为在那里,每个元素都是一种包含元素值和附加指向邻居的结构(据我所知)。
编辑:是的,这样的结构可能会使用更多的内存不必要的,特别是从一开始擦除一些元素,因为然后,内部数组仍然具有初始大小。 但是,对于大多数问题,内存不再是一个大问题,并且可能需要(耗时)的'内存优化'操作来创建一个新的更小的阵列,复制所有旧值并删除旧的内部阵列使用尽可能最小的尺寸。
扩展@Kerrek SB的评论, boost::circular_buffer<>
我认为你需要什么,例如:
#include <iostream>
#include <boost/circular_buffer.hpp>
int main()
{
boost::circular_buffer<int> cb(3);
cb.push_back(1);
cb.push_back(2);
cb.push_back(3);
for( auto i : cb) {
std::cout << i << std::endl;
}
// Increase to hold two more items
cb.set_capacity(5);
cb.push_back(4);
cb.push_back(5);
for( auto i : cb) {
std::cout << i << std::endl;
}
// Increase to hold two more items
cb.rset_capacity(7);
cb.push_front(0);
cb.push_front(-1);
for( auto i : cb) {
std::cout << i << std::endl;
}
}
TBH - 我没有看过这个实现,所以不能评论它是否会移动数据(我会非常惊讶),但是如果你拉下源代码,快速浏览一下,看看性能是否值得关注......
编辑:快速查看代码显示, push_xxx
操作确实没有移动数据,但xxx_capacity
操作确实导致移动/复制 - 为了避免这种情况,请确保该环在启动时具有足够的容量,并且可以像您一样工作希望...