std::move_iterator
        <iterator> 
 std::move_iterator is an iterator adaptor which behaves exactly like the underlying iterator (which must be at least a LegacyInputIterator  or model input_iterator (since C++20), or stronger iterator concept(since C++23)), except that dereferencing converts the value returned by the underlying iterator into an rvalue. If this iterator is used as an input iterator, the effect is that the values are moved from, rather than copied from.
iterator_type
 Iter
iterator_category
 std::iterator_traits <Iter>::iterator_category
value_type
 std::iterator_traits <Iter>::value_type
difference_type
 std::iterator_traits <Iter>::difference_type
pointer
 Iter
reference
 
iterator_type
 Iter
iterator_categoryiterator_concept
 
Iter models std::random_access_iterator 
Iter only models std::bidirectional_iterator 
Iter only models std::forward_iterator 
value_type
difference_type
pointer
Iter
reference
Iter current
 the underlying iterator    requires (!std::sized_sentinel_for <Iterator1, Iterator2>)
constexpr bool disable_sized_sentinel_for
This partial specialization of std::disable_sized_sentinel_for prevents specializations of move_iterator from satisfying sized_sentinel_for if their underlying iterators do not satisfy the concept.
| Feature-test macro | Value | Std | Feature | 
|---|---|---|---|
| __cpp_lib_move_iterator_concept | 202207L | (C++23) | Make std::move_iterator<T*> a random access iterator | 
#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)); }
Possible output:
Old contents of the vector: "this" "_" "is" "_" "an" "_" "example" New contents of the vector: "" "" "" "" "" "" "" Concatenated as string: "this_is_an_example"
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
| DR | Applied to | Behavior as published | Correct behavior | 
|---|---|---|---|
| LWG 2106 | C++11 | dereferencing a move_iteratorcould return a dangling referenceif the dereferencing the underlying iterator returns a prvalue | returns the object instead | 
| LWG 3736 | C++20 | move_iteratorwas missingdisable_sized_sentinel_forspecialization | added | 
| P2259R1 | C++20 | member iterator_categorywas defined even ifstd::iterator_traits <Iter>::iterator_category is not defined | iterator_categoryisnot defined in this case |