std::ranges::move, std::ranges::move_result
| Defined in header <algorithm>
|
||
| Call signature |
||
template< std::input_iterator I, std::sentinel_for<I> S,
std::weakly_incrementable O >
requires std::indirectly_movable<I, O>
constexpr ranges::move_result<I, O>
move( I first, S last, O d_first );
|
(1) | (since C++20) |
template< ranges::input_range R, std::weakly_incrementable O >
requires std::indirectly_movable<ranges::iterator_t<R>, O>
constexpr ranges::move_result<ranges::borrowed_iterator_t<R>, O>
move( R&& r, O d_first );
|
(2) | (since C++20) |
template< /*execution-policy*/ Ep,
std::random_access_iterator I, std::sized_sentinel_for<I> S,
std::random_access_iterator O, std::sized_sentinel_for<O> OutS >
requires std::indirectly_movable<I, O>
ranges::move_result<I, O>
move( Ep&& policy, I first, S last, O d_first, OutS d_last );
|
(3) | (since C++26) |
template< /*execution-policy*/ Ep,
/*sized-random-access-range*/ R, /*sized-random-access-range*/ OutR >
requires std::indirectly_movable<ranges::iterator_t<R>,
ranges::iterator_t<OutR>>
ranges::move_result<ranges::borrowed_iterator_t<R>,
ranges::borrowed_iterator_t<OutR>>
move( Ep&& policy, R&& r, OutR&& d_r );
|
(4) | (since C++26) |
| Helper types |
||
template< class I, class O >
using move_result = ranges::in_out_result<I, O>;
|
(5) | (since C++20) |
For the definition of /*execution-policy*/, see this page; for the definition of /*sized-random-access-range*/, see this page.
Moves the elements in the source range [first, last) or r to the destination range.
[d_first, ranges::next(d_first, ranges::distance(first, last))).[d_first, ranges::next(d_first, ranges::distance(r))).d_first is in the source range, the behavior is undefined.policy. If the destination range is exhausted before reaching the end of the source range, the remaining elements in the source range will not be moved.[d_first, d_last).d_r.The function-like entities described on this page are algorithm function objects (informally known as niebloids), that is:
- Explicit template argument lists cannot be specified when calling any of them.
- None of them are visible to argument-dependent lookup.
- When any of them are found by normal unqualified lookup as the name to the left of the function-call operator, argument-dependent lookup is inhibited.
Parameters
| first, last | - | the iterator-sentinel pair defining the source range |
| r | - | the source range |
| d_first | - | the beginning of the destination range |
| d_last | - | the sentinel of the destination range |
| d_r | - | the destination range |
| policy | - | the execution policy to use |
Return value
A ranges::move_result object where:
- The data member
inholds the an iterator past the last moved element in the source range, or an iterator to the beginning of the source range if no element is moved. - The data member
outholds and an iterator past the last move-assigned element in the destination range, or an iterator to the beginning of the destination range if no element is moved.
Complexity
Given
- N1 as
ranges::distance(first, last)orranges::distance(r), and - N2 as
ranges::distance(d_first, d_last)orranges::distance(d_r):
Exceptions
- If the temporary memory resources required for parallelization are not available, std::bad_alloc is thrown.
- If an uncaught exception is thrown while accessing objects via an algorithm argument, the behavior is determined by the execution policy (for standard policies, std::terminate is invoked).
Notes
When moving overlapping ranges, ranges::move is appropriate when moving to the left (beginning of the destination range is outside the source range) while ranges::move_backward is appropriate when moving to the right (end of the destination range is outside the source range).
Possible implementation
struct move_fn
{
template<std::input_iterator I, std::sentinel_for<I> S, std::weakly_incrementable O>
requires std::indirectly_movable<I, O>
constexpr ranges::move_result<I, O>
operator()(I first, S last, O result) const
{
for (; first != last; ++first, ++result)
*result = ranges::iter_move(first);
return {std::move(first), std::move(result)};
}
template<ranges::input_range R, std::weakly_incrementable O>
requires std::indirectly_movable<ranges::iterator_t<R>, O>
constexpr ranges::move_result<ranges::borrowed_iterator_t<R>, O>
operator()(R&& r, O result) const
{
return (*this)(ranges::begin(r), ranges::end(r), std::move(result));
}
template<ranges::forward_range R, std::weakly_incrementable O>
requires std::indirectly_movable<ranges::iterator_t<R>, O>
constexpr ranges::move_result<ranges::borrowed_iterator_t<R>, O>
operator()(R&& r, O result) const
{
return (*this)(ranges::begin(r),
ranges::next(ranges::begin(r), ranges::end(r)),
std::move(result));
}
};
inline constexpr move_fn move{};
|
Example
The following code moves thread objects (which themselves are not copyable) from one container to another.
#include <algorithm>
#include <chrono>
#include <iostream>
#include <iterator>
#include <list>
#include <thread>
#include <vector>
using namespace std::literals::chrono_literals;
void f(std::chrono::milliseconds n)
{
std::this_thread::sleep_for(n);
std::cout << "thread with n=" << n.count() << "ms ended" << std::endl;
}
int main()
{
std::vector<std::jthread> v;
v.emplace_back(f, 400ms);
v.emplace_back(f, 600ms);
v.emplace_back(f, 800ms);
std::list<std::jthread> l;
// std::ranges::copy() would not compile, because std::jthread is non-copyable
std::ranges::move(v, std::back_inserter(l));
}
Output:
thread with n=400ms ended
thread with n=600ms ended
thread with n=800ms ended
See also
(C++11) |
moves a range of elements to a new location (function template) |
(C++20) |
moves a range of elements to a new location in backwards order (algorithm function object) |
(C++20)(C++20) |
copies a range of elements to a new location (algorithm function object) |
(C++20) |
copies a range of elements in backwards order (algorithm function object) |
(C++11) |
converts the argument to an xvalue (function template) |