std::move
来自cppreference.net
| 定义于头文件 <algorithm>
|
||
template< class InputIt, class OutputIt >
OutputIt move( InputIt first, InputIt last,
OutputIt d_first );
|
(1) | (自 C++11 起) (自 C++20 起为 constexpr) |
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2 >
ForwardIt2 move( ExecutionPolicy&& policy,
ForwardIt1 first, ForwardIt1 last,
ForwardIt2 d_first );
|
(2) | (自 C++17 起) |
1) 移动范围
[first, last) 中的元素到另一个始于 d_first 的范围,从 first 开始并持续到 last。此操作后,被移动来源范围内的元素仍将包含适当类型的有效值,但不一定与移动前的值相同。2) 同 (1),但按照
policy 执行。 此重载仅在表达式
true 的值为 true 时参与重载决议:
|
|
(直至 C++20) |
|
|
(自 C++20 起) |
如果 d_first 位于范围 [first, last) 内,则行为未定义。这种情况下,可以使用 std::move_backward 代替。
参数
| first, last | - | 定义要移动的源 范围 的迭代器对 |
| d_first | - | 目标范围起始 |
| policy | - | 使用的执行策略 |
| 类型要求 | ||
-InputIt 必须满足 LegacyInputIterator 的要求。
| ||
-OutputIt 必须满足 LegacyOutputIterator 的要求。
| ||
-ForwardIt1, ForwardIt2 必须满足 LegacyForwardIterator 的要求。
| ||
返回值
指向最后一个被移动元素之后元素的迭代器。
复杂度
恰好 std::distance(first, last) 次移动赋值。
异常
带有模板参数名为 ExecutionPolicy 的重载报告错误如下:
- 如果作为算法一部分调用的函数执行时抛出异常,且
ExecutionPolicy是标准策略之一,则调用 std::terminate。对于任何其他ExecutionPolicy,行为由实现定义。 - 如果算法无法分配内存,则抛出 std::bad_alloc。
可能的实现
template<class InputIt, class OutputIt>
OutputIt move(InputIt first, InputIt last, OutputIt d_first)
{
for (; first != last; ++d_first, ++first)
*d_first = std::move(*first);
return d_first;
}
|
注解
当移动重叠范围时,std::move 适用于向左移动(目标范围起始在源范围之外),而 std::move_backward 适用于向右移动(目标范围末尾在源范围之外)。
示例
以下代码将线程对象(其本身不可复制)从一个容器移动到另一个容器。
运行此代码
#include <algorithm>
#include <chrono>
#include <iostream>
#include <iterator>
#include <list>
#include <thread>
#include <vector>
void f(int n)
{
std::this_thread::sleep_for(std::chrono::seconds(n));
std::cout << "thread " << n << " ended" << std::endl;
}
int main()
{
std::vector<std::jthread> v;
v.emplace_back(f, 1);
v.emplace_back(f, 2);
v.emplace_back(f, 3);
std::list<std::jthread> l;
// copy() would not compile, because std::jthread is noncopyable
std::move(v.begin(), v.end(), std::back_inserter(l));
}
输出:
thread 1 ended
thread 2 ended
thread 3 ended
参阅
(C++11) |
以逆序移动范围中的元素到新的位置 (函数模板 & 算法函数对象) |
(C++20) |
|
(C++11) |
将实参转换为亡值 (函数模板) |
(C++20) |
将范围中的元素移动到新位置 (算法函数对象) |