Namespaces
Variants

std::uninitialized_move

С ru.cppreference.net
 
 
Библиотека алгоритмов
Ограниченные алгоритмы и алгоритмы для диапазонов (C++20)
Ограниченные алгоритмы, например ranges::copy, ranges::sort, ...
Операции последовательности без модификации    
Пакетные операции
(C++17)
Операции поиска
Операции модификации последовательности
Операции копирования
(C++11)
(C++11)
Операции обмена
Операции преобразования
Операции генерации
Операции удаления
Операции изменения порядка
(до C++17)(C++11)
(C++20)(C++20)
Операции выборки
(C++17)

Сортировка и связанные операции
Операции разделения
(C++11)    

Операции сортировки
Операции бинарного поиска
(по разбитым диапазонам)
Операции над множествами (на отсортированных диапазонах)
Операции слияния (на отсортированных диапазонах)
Операции с кучей
Операции минимума/максимума
(C++11)
(C++17)
Операции лексикографического сравнения
Операции перестановок


Политики выполнения (C++17)
(только для демонстрации*)(C++26)

Численные операции
(C++11)
(C++17)
(C++17)    

Специализированные <memory> алгоритмы

Специализированные <random> алгоритмы
Библиотека C









 
Специализированные <алгоритмы работы с памятью>
 
Определён в заголовке <memory>
template< class InputIt, class NoThrowForwardIt >
NoThrowForwardIt uninitialized_move( InputIt first, InputIt last,
                                     NoThrowForwardIt d_first );
(1) (начиная с C++17)
(constexpr начиная с C++26)
template< class ExecutionPolicy,
          class ForwardIt, class NoThrowForwardIt >
NoThrowForwardIt uninitialized_move( ExecutionPolicy&& policy,
                                     ForwardIt first, ForwardIt last,
                                     NoThrowForwardIt d_first );
(2) (начиная с C++17)
1) Создаёт элементы в диапазоне назначения, начиная с d_first из элементов исходного диапазона [first, last) как если бы с помощью

for (; first != last; ++d_first, (void) ++first)
    ::new (voidify(*d_first))
        typename std::iterator_traits<NoThrowForwardIt>::value_type(deref-move(*iter));
return d_first;

Если во время инициализации возникает исключение, некоторые объекты в [first, last) остаются в допустимом, но неопределённом состоянии, а уже созданные объекты уничтожаются в неопределённом порядке.
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)


Если d_first + [0, std::distance(first, last)) пересекается с [first, last), поведение не определено.

(начиная с C++20)

Параметры

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

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

Как описано выше.

Исключения

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

Примечания

Когда итератор ввода разыменовывается в rvalue, поведение std::uninitialized_move совпадает с std::uninitialized_copy.

Макрос проверки возможностей Значение Стандарт Возможность
__cpp_lib_raw_memory_algorithms 202411L (C++26) constexpr для специализированных <memory> алгоритмов, (1)

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

template<class InputIt, class NoThrowForwardIt>
constexpr NoThrowForwardIt uninitialized_move(InputIt first, InputIt last,
                                              NoThrowForwardIt d_first)
{
    using ValueType = typename std::iterator_traits<NoThrowForwardIt>::value_type;
    auto current = d_first;
    try
    {
        for (; first != last; ++first, (void) ++current)
        {
            auto addr = static_cast<void*>(std::addressof(*current));
            if constexpr (std::is_lvalue_reference_v<decltype(*first)>)
                ::new (addr) ValueType(std::move(*first));
            else
                ::new (addr) ValueType(*first);
        }
        return current;
    }
    catch (...)
    {
        std::destroy(d_first, current);
        throw;
    }
}
**Примечание:** Весь код C++ внутри тегов `
` и `` оставлен без изменений, как и требовалось. HTML-теги и атрибуты также сохранены в оригинальном виде.

Пример

#include <cstdlib>
#include <iomanip>
#include <iostream>
#include <memory>
#include <string>

void print(auto rem, auto first, auto last)
{
    for (std::cout << rem; first != last; ++first)
        std::cout << std::quoted(*first) << ' ';
    std::cout << '\n';
}

int main()
{
    std::string in[]{"Home", "Work!"};
    print("initially, in: ", std::begin(in), std::end(in));
    
    if (constexpr auto sz = std::size(in);
        void* out = std::aligned_alloc(alignof(std::string), sizeof(std::string) * sz))
    {
        try
        {
            auto first{static_cast<std::string*>(out)};
            auto last{first + sz};
            std::uninitialized_move(std::begin(in), std::end(in), first);
            
            print("after move, in: ", std::begin(in), std::end(in));
            print("after move, out: ", first, last);
            
            std::destroy(first, last);
        }
        catch (...)
        {
            std::cout << "Exception!\n";
        }
        std::free(out);
    }
}

Возможный вывод:

initially, in: "Home" "Work!"
after move, in: "" ""
after move, out: "Home" "Work!"

Сообщения о дефектах

Следующие сообщения о дефектах, изменяющих поведение, были применены ретроактивно к ранее опубликованным стандартам C++.

DR Применено к Поведение в опубликованной версии Правильное поведение
LWG 3918 C++17 перемещающее конструирование всегда выполняется, даже
если входной итератор разыменовывается в prvalue
перемещающее конструирование не выполняется
в этом случае

Смотрите также

копирует диапазон объектов в неинициализированную область памяти
(шаблон функции)
перемещает несколько объектов в неинициализированную область памяти
(шаблон функции)
перемещает диапазон объектов в неинициализированную область памяти
(функциональный объект алгоритма)