减lessstl向量的容量

有没有办法减lessvector的容量?

我的代码将值插入到一个向量中(事先不知道它们的数量),当这些完成时,向量仅用于读取操作。

我想我可以创build一个新的vector,做一个.reseve()的大小和复制项目,但我不喜欢额外的复制操作。

PS:我不关心便携式解决scheme,只要它适用于gcc。

std::vector<T>(v).swap(v); 

用另一个vector交换内容交换容量。

  std::vector<T>(v).swap(v); ==> is equivalent to std::vector<T> tmp(v); // copy elements into a temporary vector v.swap(tmp); // swap internal vector data 

Swap()只会改变内部的数据结构。

用C ++ 11,你可以调用成员函数shrink_to_fit() 。 标准草案第23.2.6.2节说:

shrink_to_fit是一个非约束请求,用于将capacity()减小到size()[注意:该请求不具有约束力,可以实现特定于实现的优化。 – 注意]

去看Scott Meyers有效的STL第17项。

基本上你不能直接减lessstd :: vector的存储大小。 resize和重新放置绝不会减less容器的实际内存占用量。 “技巧”是创build一个合适大小的新容器,复制数据并将其与当前容器交换。 如果我们想清除一个容器,这只是简单的:

 std::vector<T>().swap(v); 

如果我们必须复制数据,那么我们需要复制:

 std::vector<T>(v).swap(v); 

这样做是用旧数据创build一个新的向量,做任何需要的效果所需的副本。 然后调用swap将只交换对象之间的内部缓冲区。 在行的末尾,创build的临时向量被删除,但是它具有旧向量的内容,而旧向量具有来自新副本的内容,这是我们需要的确切大小。

惯用的解决scheme是与新构build的向量交换。

 vector<int>().swap(v); 

编辑:我误解了这个问题。 上面的代码将清除vector。 OP要保持元素不变,只能将capacity()缩小到size()

如果aJ的代码能够做到这一点很难说。 我怀疑有便携式解决scheme。 对于gcc ,你将不得不看看他们特定的vector实现。

编辑 :所以我偷看libstdc ++实现。 看来aJ的解决scheme确实会起作用。

 vector<int>(v).swap(v); 

见第 232行的来源 。

不,不能在不复制的情况下减lessvector的容量。 但是,您可以通过每次插入内容时检查capacity()和call reserve()来控制新的分配增长量。 std :: vector的默认行为是在每次需要新容量时将其容量增大2倍。 你可以通过你自己的魔法比例来增长它:

 template <typename T> void myPushBack(std::vector<T>& vec, const T& val) { if (vac.size() + 1 == vac.capacity()) { vac.reserve(vac.size() * my_magic_ratio); } vec.push_back(val); } 

如果你的技术有点诡异,你可以随时传递你自己的分配器,做任何你需要做的事来回收未使用的容量。

我并不是说GCC没有一个方法可以在没有副本的情况下做你想做的事情,但是实现(我认为)会很棘手,因为向量需要使用一个Allocator对象来分配和释放内存,而接口Allocator不包含reallocate()方法。 我不认为这是不可能的,但可能是棘手的。

如果你担心你的vector的开销,那么也许你应该考虑使用另一种types的数据结构。 你提到,一旦你的代码完成初始化向量,它就成为一个只读过程。 我会build议去开放式数组,这将允许程序在编译时决定其容量。 或者一个链表可能更适合你的需求。
让我知道我是否完全误解了你所得到的。

-UBcse

老的线程,我知道,但万一任何人在将来查看这个..在C 11中有shrink_to_fit(),但由于它是一个非绑定的请求,行为将取决于其实施。

请参阅: http : //en.cppreference.com/w/cpp/container/vector/shrink_to_fit

获得Scott Myers的“Effective STL”书。 它在减lessvector容量方面有完整的项目。