Spec-Zone.ru › C++

std::move

Определён в заголовочном файле <algorithm>
template< class InputIt, class OutputIt >
OutputIt move( InputIt first, InputIt last, OutputIt d_first );
(1) (начиная с C++11)
(constexpr начиная с C++20)
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2 >
ForwardIt2 move( ExecutionPolicy&& policy,
                 ForwardIt1 first, ForwardIt1 last, ForwardIt2 d_first );
(2) (начиная с C++17)

Перемещает все элементы из исходного диапазона [first, last) в целевой диапазон [d_first, std::next(d_first, std::distance(first, last))).

1) Перемещение начинается с first и продолжается до last.
Если d_first находится в исходном диапазоне, поведение не определено.
2) То же, что и (1), но порядок перемещения определяется policy.
Эта перегрузка участвует в разрешении перегрузки, только если значение следующего выражения равно true:

std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>

(до C++20)

std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>

(начиная с C++20)
Если исходный и целевой диапазоны пересекаются, поведение не определено.

Параметры

first, last - пара итераторов, задающая исходный диапазон
d_first - начало целевого диапазона
policy - используемая политика выполнения
Требования к типам
-InputIt должен соответствовать требованиям LegacyInputIterator.
-OutputIt должен соответствовать требованиям LegacyOutputIterator.
-ForwardIt1, ForwardIt2 должен соответствовать требованиям LegacyForwardIterator.

Возвращаемое значение

Итератор за концом целевого диапазона.

Сложность

Ровно std::distance(first, last) присваиваний.

Исключения

2) В ходе выполнения:
  • Если требуемые для распараллеливания временные ресурсы памяти недоступны, выбрасывается исключение std::bad_alloc.
  • Если при обращении к объектам через аргумент алгоритма выбрасывается необработанное исключение, поведение определяется политикой выполнения (для стандартных политик вызывается std::terminate).

Возможная реализация

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

См. также

ranges::move
(C++20)
перемещает диапазон элементов в новое место
(объект-функция алгоритма)
move_backward
(C++11)
перемещает диапазон элементов в новое место в обратном порядке
(шаблон функции и объект-функция алгоритма)
ranges::move_backward
(C++20)
move
(C++11)
преобразует аргумент в xvalue
(шаблон функции)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/algorithm/move

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API