Namespaces
Variants

std:: uninitialized_move_n

From cppreference.net
Memory management library
( exposition only* )
Allocators
Uninitialized memory algorithms
Constrained uninitialized memory algorithms
Memory resources
Uninitialized storage (until C++20)
( until C++20* )
( until C++20* )
( until C++20* )

Garbage collector support (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
Определено в заголовке <memory>
template < class InputIt, class Size, class NoThrowForwardIt >

std:: pair < InputIt, NoThrowForwardIt >
uninitialized_move_n ( InputIt first, Size count,

NoThrowForwardIt d_first ) ;
(1) (начиная с C++17)
(constexpr начиная с C++26)
template < class ExecutionPolicy,

class ForwardIt, class Size, class NoThrowForwardIt >
std:: pair < ForwardIt, NoThrowForwardIt >
uninitialized_move_n ( ExecutionPolicy && policy, ForwardIt first,

Size count, NoThrowForwardIt d_first ) ;
(2) (начиная с C++17)
1) Копирует элементы из first + [ 0 , count ) (используя семантику перемещения, если поддерживается) в неинициализированную область памяти, начинающуюся с d_first , как если бы

for ( ; count > 0 ; ++ d_first, ( void ) ++ first, -- count )
:: new ( voidify ( * d_first ) )
typename std:: iterator_traits < NoThrowForwardIt > :: value_type ( /* value */ ) ;
return { first, d_first } ;

где /* value */ это std :: move ( * first ) если * first имеет тип lvalue-ссылки, или * first в противном случае.
Если во время инициализации возникает исключение, некоторые объекты в first + [ 0 , count ) остаются в допустимом, но неопределённом состоянии, а уже созданные объекты уничтожаются в неопределённом порядке.
2) То же, что и (1) , но выполняется в соответствии с policy .
Эта перегрузка участвует в разрешении перегрузки только при выполнении всех следующих условий:

std:: is_execution_policy_v < std:: decay_t < ExecutionPolicy >> является true .

(до C++20)

std:: is_execution_policy_v < std:: remove_cvref_t < ExecutionPolicy >> является true .

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


Если d_first + [ 0 , count ) пересекается с first + [ 0 , count ) , поведение не определено.

(since C++20)

Содержание

Параметры

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

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

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

Сложность

Линейно по count .

Исключения

Перегрузка с параметром шаблона с именем ExecutionPolicy сообщает об ошибках следующим образом:

  • Если выполнение функции, вызванной как часть алгоритма, выбрасывает исключение и ExecutionPolicy является одним из стандартных политик , std::terminate вызывается. Для любой другой ExecutionPolicy поведение определяется реализацией.
  • Если алгоритму не удается выделить память, std::bad_alloc выбрасывается.

Примечания

Когда входной итератор разыменовывается в rvalue, поведение std::uninitialized_move_n аналогично поведению std::uninitialized_copy_n .

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

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

template<class InputIt, class Size, class NoThrowForwardIt>
constexpr std::pair<InputIt, NoThrowForwardIt>
    uninitialized_move_n(InputIt first, Size count, NoThrowForwardIt d_first)
{
    using ValueType = typename std::iterator_traits<NoThrowForwardIt>::value_type;
    NoThrowForwardIt current = d_first;
    try
    {
        for (; count > 0; ++first, (void) ++current, --count) {
            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);
        }
    }
    catch (...)
    {
        std::destroy(d_first, current);
        throw;
    }
    return {first, current};
}
**Примечание:** Весь код 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[]{"One", "Definition", "Rule"};
    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_n(std::begin(in), sz, 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: "One" "Definition" "Rule" 
after move, in: "" "" "" 
after move, out: "One" "Definition" "Rule"

Отчеты о дефектах

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

DR Applied to Behavior as published Correct behavior
LWG 3870 C++20 this algorithm might create objects on a const storage kept disallowed
LWG 3918 C++17 additional temporary materialization was required
when the input iterator deferences to a prvalue
copies the element in this case

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

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