有没有减少向量的容量的方法吗?
我的代码值插入到载体中(不知道它们的数量预先),并且当这个完成时,载体仅用于读操作。
我想我可以创建一个新的载体,做一个.reseve()的大小和复制的项目,但我真的不喜欢额外的复制操作。
PS:我不喜欢一个便携式解决方案,只要它适用于GCC。
有没有减少向量的容量的方法吗?
我的代码值插入到载体中(不知道它们的数量预先),并且当这个完成时,载体仅用于读操作。
我想我可以创建一个新的载体,做一个.reseve()的大小和复制的项目,但我真的不喜欢额外的复制操作。
PS:我不喜欢一个便携式解决方案,只要它适用于GCC。
std::vector<T>(v).swap(v);
与另一向量交换的内容交换的能力。
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
交换()将只改变内部数据结构。
随着C ++ 11,你可以调用成员函数shrink_to_fit()
该草案标准节23.2.6.2说:
shrink_to_fit
是减少非绑定请求capacity()
到size()
[注:该请求是非约束以允许特定于实现的优化纬度。 末端注]
去看看斯科特迈尔斯有效的STL 17项。
基本上你不能直接减少的存储大小std::vector
。 resize()
和reseve()
将永远不会减少容器的实际内存占用。 该“绝招”是创建大小合适的新的容器,将数据复制和交换与当前容器。 如果我们想清楚的容器出来这很简单:
std::vector<T>().swap(v);
如果我们要拷贝过来,然后将数据我们需要做的副本:
std::vector<T>(v).swap(v);
这样做是创建与旧的数据,这样做会在有你需要的效果的任何操作需要复制一个新的载体。 然后调用swap()
将只是交换对象之间的内部缓冲区。 在生产线的末端时创建的临时矢量被删除,但它从旧矢量有胆量和老矢量具有从新副本这是我们需要的确切大小的胆量。
惯用的解决方案是与新构建的载体切换。
vector<int>().swap(v);
编辑:我误解了问题。 上面的代码将清除矢量。 OP希望保持不变的元素,只有收缩capacity()
到size()
这是很难说,如果AJ的代码将做到这一点。 我怀疑有便携式解决方案。 对于gcc
,你必须看看他们的具体实现的vector
。
编辑 :所以我在的libstdc ++实现偷看。 看来,AJ的解决方案确实会工作。
vector<int>(v).swap(v);
见源 ,线232。
不,你不能减小载体的容量,而无需复制。 但是,你可以控制通过检查能力()和呼叫储备()每次插入一些时间多少新分配的增长。 性病:: 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()
方法。 我不认为这是不可能的事,但它可能会非常棘手。
如果你担心你的矢量的开销,那么也许你应该寻找到使用其他类型的数据结构。 你提到的,一旦你的代码完成初始化向量它成为一个只读的过程。 我建议用开放式阵列,这将允许该程序在编译时决定其容量会。 或许链表会更适合您的需求。
还是让我知道,如果我完全误解你是得到什么。
-UBcse
旧线,我知道,但如果有人在将来观看这个..有shrink_to_fit()在C ++ 11,但因为它是一个非绑定请求,该行为将取决于其实施。
请参阅: http://en.cppreference.com/w/cpp/container/vector/shrink_to_fit
获取由斯科特·迈尔斯的“有效STL”一书。 这对降低载体的能力完整的项目强制。