std::move
来自 cppreference.cn
定义于头文件 <algorithm> |
||
template< class InputIt, class OutputIt > OutputIt move( InputIt first, InputIt last, |
(1) | (自 C++11 起) (constexpr 自 C++20 起) |
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2 > ForwardIt2 move( ExecutionPolicy&& policy, |
(2) | (自 C++17 起) |
1) 将范围
[
first,
last)
中的元素移动到始于 d_first 的另一范围,从 first 开始并前进到 last。 在此操作后,被移动来源范围中的元素仍将保有适当类型的合法值,但不必然与移动前的值相同。2) 同于 (1),但根据 policy 执行。
仅当满足下列所有条件时,此重载才参与重载决议
std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> 为 true。 |
(直至 C++20) |
std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>> 为 true。 |
(自 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++11) |
将参数转换为 xvalue (函数模板) |
(C++20) |
将元素范围移动到新位置 (算法函数对象) |