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부터)
(C++26부터 constexpr)
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 ) 범위와 겹치는 경우, 동작은 정의되지 않습니다.

(C++20부터)

목차

매개변수

first - 이동할 요소 범위의 시작
d_first - 대상 범위의 시작
count - 이동할 요소의 개수
policy - 사용할 실행 정책
타입 요구사항
-
InputIt LegacyInputIterator 요구사항을 충족해야 함
-
ForwardIt LegacyForwardIterator 요구사항을 충족해야 함
-
NoThrowForwardIt LegacyForwardIterator 요구사항을 충족해야 함
-
NoThrowForwardIt 의 유효한 인스턴스를 통한 증가, 할당, 비교, 간접 참조 연산은 예외를 발생시켜서는 안 됨

반환값

위에서 설명한 바와 같습니다.

복잡도

count 에 선형적으로 비례합니다.

예외

ExecutionPolicy 라는 템플릿 매개변수를 사용하는 오버로드는 다음과 같이 오류를 보고합니다:

  • 알고리즘의 일부로 호출된 함수 실행 중 예외가 발생하고 ExecutionPolicy 표준 정책 중 하나인 경우, std::terminate 가 호출됩니다. 다른 ExecutionPolicy 의 경우 동작은 구현에 따라 정의됩니다.
  • 알고리즘이 메모리 할당에 실패하는 경우, std::bad_alloc 이 throw됩니다.

참고 사항

입력 반복자가 rvalue로 역참조될 때, std::uninitialized_move_n 의 동작은 std::uninitialized_copy_n 과 동일합니다.

기능 테스트 매크로 표준 기능
__cpp_lib_raw_memory_algorithms 202411L (C++26) constexpr for 특수화된 메모리 알고리즘 , ( 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++ 코드 블록으로 구성되어 있으며, 지시사항에 따라 ` `, `
`, `` 태그 내의 텍스트와 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 적용 대상 게시된 동작 올바른 동작
LWG 3870 C++20 이 알고리즘이 const 저장 공간에 객체를 생성할 수 있음 허용되지 않음으로 유지
LWG 3918 C++17 입력 반복자가 prvalue를 역참조할 때
추가적인 임시 materialization이 필요했음
이 경우 요소를 복사함

참고 항목

객체 범위를 초기화되지 않은 메모리 영역으로 이동
(함수 템플릿)
지정된 개수의 객체를 초기화되지 않은 메모리 영역으로 복사
(함수 템플릿)
지정된 개수의 객체를 초기화되지 않은 메모리 영역으로 이동
(알고리즘 함수 객체)