如何高效覆盖std::vector<T>且不改变源vector的大小?
解决方案:在保留源vector大小的前提下高效转移元素
问题背景
现有两个std::vector<T>对象old_vec和new_vec,已保证二者大小相同或均未初始化。需要实现类似old_vec = new_vec的赋值逻辑,但有以下要求:
- 避免拷贝:T可能是大型对象,需最大化效率
- 保留源容器大小:操作后
new_vec的大小不能改变(后续会重新计算其内容) std::move(source)无法满足需求,因为它会将源vector的大小置为0
可行方案
方案1:使用std::move算法逐个移动元素
利用标准库的std::move算法(注意区分用于右值转换的std::move函数),可以将源vector的每个元素移动到目标vector,同时保留源vector的容器大小(仅内部元素变为可析构但值未定义的状态,符合后续重新计算的需求)。
示例代码:
#include <iostream> #include <vector> #include <algorithm> #include <utility> // 自定义类型示例,需支持移动语义 class MyClass { public: MyClass(int val) : value(val) {} // 默认移动构造/赋值 MyClass(MyClass&&) = default; MyClass& operator=(MyClass&&) = default; private: int value; }; int main() { std::vector<MyClass> new_vec = {MyClass(1), MyClass(2), MyClass(3)}; std::vector<MyClass> old_vec = {MyClass(10), MyClass(20), MyClass(30)}; // 移动元素,保留new_vec的大小 std::move(new_vec.begin(), new_vec.end(), old_vec.begin()); // new_vec.size() 仍为3,内部元素状态可析构但未定义(后续可重新赋值) // old_vec 已获取new_vec原元素的所有权 return 0; }
方案2:手动循环移动元素
如果需要更直观的控制,可以手动遍历每个元素,逐个执行移动赋值:
for (size_t i = 0; i < new_vec.size(); ++i) { old_vec[i] = std::move(new_vec[i]); }
关键说明
- 效率保障:所有操作均使用移动语义,对于支持移动的类型,代价远低于拷贝(仅转移资源所有权,无深拷贝)
- 源容器大小不变:移动操作仅修改元素内部状态,不会改变vector的
size()或capacity() - 前提条件:必须确保两个vector的大小一致(题目已保证),否则目标vector空间不足会导致未定义行为
- 类型要求:自定义类型T需定义移动构造/移动赋值(可显式默认
=default),否则会退化为拷贝操作
内容的提问来源于stack exchange,提问作者Mathieu
相关产品推荐
相关产品推荐

