std::move
ja.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 である場合にのみオーバーロード解決に参加します:
|
|
(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が 標準ポリシー の1つである場合、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) |
引数を xvalue に変換する (関数テンプレート) |
(C++20) |
要素の範囲を新しい位置に移動する (アルゴリズム関数オブジェクト) |