std::move_iterator
From cppreference.com
| ヘッダ <iterator> で定義 |
||
| template< class Iter > class move_iterator; |
(C++11以降) | |
std::move_iteratorはイテレータアダプタであり、基底イテレータ(少なくともLegacyInputIteratorまたはinput_iteratorをモデル化するもの(C++20以降)、またはより強力なイテレータコンセプト(C++23以降)である必要がある)と全く同じように動作しますが、間接参照すると基底イテレータが返す値が右辺値に変換されます。このイテレータを入力イテレータとして使用すると、値はコピーされるのではなく、ムーブされます。
目次 |
[編集] 入れ子型
|
(C++20まで) | ||||||||||||||||||||
|
(C++20以降) |
[編集] データメンバ
| メンバ | 説明 |
Iter current |
基底イテレータ (説明用のメンバオブジェクト*) |
[編集] メンバ関数
新しいmove_iteratorを構築する(public member function) | |
別のmove_iteratorを代入する(public member function) | |
| 基底イテレータにアクセスする (public member function) | |
| 指し示す要素にアクセスする (public member function) | |
| インデックスで要素にアクセスする (public member function) | |
move_iteratorを進める、または減らす(public member function) |
[編集] 非メンバ関数
| (C++11)(C++11)(C++20で削除)(C++11)(C++11)(C++11)(C++11)(C++20) |
基底イテレータを比較する (関数テンプレート) |
| 基底イテレータと基底センチネルを比較する (関数テンプレート) | |
| (C++11) |
イテレータを進める (関数テンプレート) |
| (C++11) |
2つのイテレータアダプタ間の距離を計算する (関数テンプレート) |
| 基底イテレータと基底センチネル間の距離を計算する (関数テンプレート) | |
| (C++20) |
基底イテレータの間接参照の結果を関連する右辺値参照型にキャストする (関数) |
| (C++20) |
2つの基底イテレータが指すオブジェクトをスワップする (関数テンプレート) |
| (C++11) |
引数から型を推論してstd::move_iteratorを作成する (関数テンプレート) |
[編集] ヘルパーテンプレート
| template< class Iterator1, class Iterator2 > requires (!std::sized_sentinel_for<Iterator1, Iterator2>) |
(C++20以降) | |
このstd::disable_sized_sentinel_forの部分特殊化は、基底イテレータがコンセプトを満たさない場合、move_iteratorの特殊化がsized_sentinel_forを満たさないようにします。
[編集] 備考
| 機能テストマクロ | 値 | 規格 | 機能 |
|---|---|---|---|
__cpp_lib_move_iterator_concept |
202207L |
(C++23) | std::move_iterator<T*>をランダムアクセスイテレータにする |
[編集] 例
このコードを実行
#include <algorithm> #include <iomanip> #include <iostream> #include <iterator> #include <ranges> #include <string> #include <string_view> #include <vector> void print(const std::string_view rem, const auto& v) { std::cout << rem; for (const auto& s : v) std::cout << std::quoted(s) << ' '; std::cout << '\n'; }; int main() { std::vector<std::string> v{"this", "_", "is", "_", "an", "_", "example"}; print("Old contents of the vector: ", v); std::string concat; for (auto begin = std::make_move_iterator(v.begin()), end = std::make_move_iterator(v.end()); begin != end; ++begin) { std::string temp{*begin}; // moves the contents of *begin to temp concat += temp; } // Starting from C++17, which introduced class template argument deduction, // the constructor of std::move_iterator can be used directly: // std::string concat = std::accumulate(std::move_iterator(v.begin()), // std::move_iterator(v.end()), // std::string()); print("New contents of the vector: ", v); print("Concatenated as string: ", std::ranges::single_view(concat)); }
実行結果の例
Old contents of the vector: "this" "_" "is" "_" "an" "_" "example" New contents of the vector: "" "" "" "" "" "" "" Concatenated as string: "this_is_an_example"
[編集] 欠陥レポート
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| LWG 2106 | C++11 | move_iteratorの間接参照がダングリング参照を返す可能性がある基底イテレータの間接参照がprvalueを返す場合 |
オブジェクトを返す 代わりにオブジェクトを返す |
| LWG 3736 | C++20 | move_iteratorにdisable_sized_sentinel_forの特殊化が欠けていた |
追加された |
| P2259R1 | C++20 | メンバiterator_categoryは、たとえstd::iterator_traits<Iter>::iterator_categoryが定義されていない場合でも定義されていた |
この場合、iterator_categoryは定義されていない |
[編集] 関連項目
| (C++11) |
引数から型を推論してstd::move_iteratorを作成する (関数テンプレート) |
| (C++20) |
std::move_iteratorのセンチネルアダプタ (クラステンプレート) |