std::make_move_iterator()的作用是什么?拆分vector用它有何优势?
关于std::make_move_iterator()的作用与优势
std::make_move_iterator是C++11引入的工具,核心作用是把普通迭代器包装成移动迭代器——这类迭代器被解引用时,返回的是元素的右值引用(T&&),而非普通迭代器的左值引用(T&)。
你当前的代码用的是int类型的vector,所以看起来用不用它输出都一样——因为int是基本类型,移动和拷贝的开销几乎没有区别。但如果换成非基本类型(比如std::string、自定义类、其他容器),它的优势就非常明显了:
核心优势
1. 避免不必要的深拷贝,大幅提升性能
当容器里存的是需要深拷贝的类型(比如std::string,内部持有字符数组),用普通迭代器构造新容器时,会逐个调用元素的拷贝构造函数——这意味着要复制底层的内存资源,开销很大。
而用移动迭代器的话,会调用元素的移动构造函数:只是把原元素的内部资源(比如string的指针)直接转移给新元素,不需要复制内存,速度快得多,尤其当容器元素数量多、单个元素体积大时,性能差异会非常显著。
2. 明确表达代码意图
使用std::make_move_iterator相当于给阅读代码的人传递一个明确信号:我要把原容器中这部分元素的资源所有权转移到新容器,原容器的这部分元素之后会处于「可析构、可赋值但不可使用」的状态(标准称之为valid but unspecified state)。比普通拷贝的写法更清晰,避免他人误解你还需要保留原元素的内容。
直观示例(非基本类型)
把你的代码改成存储std::string,就能看到差异:
#include <iostream> #include <vector> #include <string> int main() { std::vector<std::string> foo = {"apple", "banana", "cherry", "date"}; // 普通拷贝构造v1 std::vector<std::string> v1(foo.begin(), foo.begin() + 2); // 移动构造v2 std::vector<std::string> v2(std::make_move_iterator(foo.begin() + 2), std::make_move_iterator(foo.end())); std::cout << "v1: "; for (const auto& s : v1) std::cout << s << " "; std::cout << "\nv2: "; for (const auto& s : v2) std::cout << s << " "; std::cout << "\n原foo的后两个元素状态: "; for (auto it = foo.begin() + 2; it != foo.end(); ++it) { std::cout << (it->empty() ? "[已被移动,内容为空]" : *it) << " "; } return 0; }
运行输出:
v1: apple banana v2: cherry date 原foo的后两个元素状态: [已被移动,内容为空] [已被移动,内容为空]
可以看到,原容器的后两个string被移动后变成了空,而v2直接接管了它们的资源,没有做任何深拷贝。
总结
- 对于int这类基本类型,
std::make_move_iterator没有实际性能提升,但使用也不会有问题; - 对于支持移动语义的复杂类型,它能避免昂贵的深拷贝,同时让代码意图更明确——这就是为什么评论说它是一种「改进」。
内容的提问来源于stack exchange,提问作者Drew
相关产品推荐
相关产品推荐

