前面一节我们学习了旋转复制算法 rotate_copy() 函数,读者是否还记得它的功能是什么吗?没错,该函数能够在保持原序列不变的前提下生成旋转后的副本。本节我们将学习一个工具算法——move() 函数。"move" 意为"移动",从名称就能看出,这个函数用于将元素从一个位置移动到另一个位置,主要应用于批量高效移动复杂对象。
move() 函数的语法格式如下:
template< class InputIt, class OutputIt > OutputIt move( InputIt first, InputIt last, OutputIt ret );
move(first, last, ret) 函数的功能是:将区间 [first, last) 中的元素移动到以 ret 为起始位置的目标区域。与 copy() 不同,move() 执行的是移动语义,对于支持移动语义的类型(如 std::string、std::vector 等),它会将资源所有权从源对象转移给目标对象,而不是进行深拷贝。该函数返回指向目标序列中最后移动元素的下一个位置的迭代器。比如我们有一个字符串序列:{"Dotcpp", "数据结构教程", "C语言教程", "算法竞赛教程", "Java教程"},使用 move() 移动到目标序列后,源序列中的字符串将变为有效但未指定的状态(通常为空字符串),而目标序列获得这些字符串的所有权。
下面我们通过代码来演示 move() 函数的实际应用:
#include<iostream>
#include<vector>
#include<algorithm>
#include<iterator>//移动迭代器
#include<string>
using namespace std;
/*move(first, last, ret) 函数*/
void test() {
vector<string> v1{"Dotcpp", "数据结构教程", "C语言教程", "算法竞赛教程", "Java教程"}; //原容器
vector<string> v2;//目标容器
/*移动前*/
cout << "移动前:\n";
cout << "原容器有字符串:";
for_each(v1.begin(), v1.end(), [](const string&s){
cout << s<< " ";
});
cout << '\n';
/*开始移动*/
move(v1.begin(),v1.end(),back_inserter(v2)) ;
/*移动后*/
cout << "移动之后:\n原容器有字符串:";
for_each(v1.begin(), v1.end(), [](const string&s){
cout << s;
});
cout << '\n';
cout << "原容器存储元素个数总和为:【" << v1.size() << "】\n";
cout << "目标容器有字符串:";
for_each(v2.begin(), v2.end(), [](const string&s){
cout << s;
});
}
int main(){
system("title dotcpp.com");
test();
return 0;
}编译结果如下:

通过观察输出我们发现,v1仍有5个元素但内容都为空字符串,v2也有5个元素且包含了原始数据。这是因为v1中每个字符串在堆区的资源都被转移给了v2,v1只剩下空的string对象外壳。
总结:move() 函数提供了一个高效的资源转移机制,它利用移动语义避免了不必要的深拷贝操作,特别适合处理大型对象、智能指针和不可复制的资源;同时在性能要求高的应用场景中,move() 是优化内存使用和提高程序效率的重要工具,是现代 C++ 编程中不可或缺的高效函数。
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程