std::ranges::move, std::ranges::move_result
Определён в заголовке <algorithm> | ||
|---|---|---|
| Сигнатура вызова | ||
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) | (с 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) | (с 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) | (с 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) | (с C++26) |
| Вспомогательные типы | ||
template< class I, class O > using move_result = ranges::in_out_result<I, O>; | (5) | (с C++20) |
Определение /*execution-policy*/ см. на этой странице; определение /*sized-random-access-range*/ см. на этой странице.
Перемещает элементы из исходного диапазона [first, last) или r в целевой диапазон.
[d_first, ranges::next(d_first, ranges::distance(first, last))).[d_first, ranges::next(d_first, ranges::distance(r))).d_first находится в исходном диапазоне, поведение не определено.policy. Если целевой диапазон исчерпан до достижения конца исходного диапазона, оставшиеся элементы исходного диапазона перемещены не будут.[d_first, d_last).d_r.Описанные на этой странице функциональные объекты являются функциональными объектами алгоритмов (неофициально называемыми niebloids), то есть:
- При вызове любого из них нельзя указывать явные списки аргументов шаблона.
- Ни один из них не виден при поиске с учётом аргументов.
- Если какой-либо из них найден при обычном неквалифицированном поиске как имя слева от оператора вызова функции, поиск с учётом аргументов подавляется.
Параметры
| first, last | - | пара «итератор—сентинел», задающая исходный диапазон |
| r | - | исходный диапазон |
| d_first | - | начало целевого диапазона |
| d_last | - | сентинел целевого диапазона |
| d_r | - | целевой диапазон |
| policy | - | политика выполнения, которую следует использовать |
Возвращаемое значение
Объект ranges::move_result, в котором:
- Член данных
inсодержит итератор, указывающий на элемент после последнего перемещённого элемента исходного диапазона, либо итератор на начало исходного диапазона, если ни один элемент не перемещён. - Член данных
outсодержит итератор, указывающий на элемент после последнего элемента целевого диапазона, которому было присвоено значение перемещением, либо итератор на начало целевого диапазона, если ни один элемент не перемещён.
Сложность
Пусть
- \(\scriptsize N_1\)N1 — это
ranges::distance(first, last)илиranges::distance(r), а - \(\scriptsize N_2\)N2 — это
ranges::distance(d_first, d_last)илиranges::distance(d_r):
Исключения
3,4) Во время выполнения:- Если требуемые для распараллеливания временные ресурсы памяти недоступны, выбрасывается
std::bad_alloc. - Если при доступе к объектам через аргумент алгоритма возникает необработанное исключение, поведение определяется политикой выполнения (для стандартных политик вызывается
std::terminate).
Примечания
При перемещении перекрывающихся диапазонов ranges::move подходит для перемещения влево (начало целевого диапазона находится за пределами исходного диапазона), а ranges::move_backward подходит для перемещения вправо (конец целевого диапазона находится за пределами исходного диапазона).
Возможная реализация
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{};
|
Пример
Следующий код перемещает объекты потоков (которые сами по себе не копируются) из одного контейнера в другой.
#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));
}
Вывод:
thread with n=400ms ended thread with n=600ms ended thread with n=800ms ended
См. также
|
(C++11) | перемещает диапазон элементов в новое место (шаблон функции) |
|
(C++20) | перемещает диапазон элементов в новое место в обратном порядке (функциональный объект алгоритма) |
|
(C++20)(C++20) | копирует диапазон элементов в новое место (функциональный объект алгоритма) |
|
(C++20) | копирует диапазон элементов в обратном порядке (функциональный объект алгоритма) |
|
(C++11) | преобразует аргумент в xvalue (шаблон функции) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/algorithm/ranges/move