Namespaces
Variants

std:: uninitialized_move

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 NoThrowForwardIt >

NoThrowForwardIt uninitialized_move ( InputIt first, InputIt last,

NoThrowForwardIt d_first ) ;
(1) (C++17부터)
(C++26부터 constexpr)
template < class ExecutionPolicy,

class ForwardIt, class NoThrowForwardIt >
NoThrowForwardIt uninitialized_move ( ExecutionPolicy && policy,
ForwardIt first, ForwardIt last,

NoThrowForwardIt d_first ) ;
(2) (C++17부터)
1) [ first , last ) 범위의 요소들을(지원되는 경우 move semantics 사용) d_first 로 시작하는 초기화되지 않은 메모리 영역으로 다음과 같이 복사합니다:

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

여기서 /* value */ std :: move ( * first ) 입니다, 만약 * first 가 lvalue 참조 타입인 경우, 그렇지 않으면 * first 입니다.
초기화 과정에서 예외가 발생하면, [ first , last ) 범위 내 일부 객체는 유효하지만 지정되지 않은 상태로 남게 되며, 이미 생성된 객체들은 지정되지 않은 순서로 파괴됩니다.
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 , std:: distance ( first, last ) ) [ first , last ) 와 겹치는 경우, 동작은 정의되지 않습니다.

(C++20부터)

목차

매개변수

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

반환값

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

복잡도

first last 사이의 거리에 선형적으로 비례합니다.

예외

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

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

참고 사항

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

기능 테스트 매크로 표준 기능
__cpp_lib_raw_memory_algorithms 202411L (C++26) constexpr for 특수화된 메모리 알고리즘 , ( 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;
    }
}

예제

#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 3870 C++20 이 알고리즘이 const 저장 공간에 객체를 생성할 수 있음 허용되지 않음으로 유지
LWG 3918 C++17 입력 반복자가 prvalue를 역참조할 때
추가적인 임시 materialization이 필요했음
이 경우 요소를 복사함

참고 항목

객체 범위를 초기화되지 않은 메모리 영역으로 복사합니다
(function template)
지정된 개수의 객체를 초기화되지 않은 메모리 영역으로 이동합니다
(function template)
객체 범위를 초기화되지 않은 메모리 영역으로 이동합니다
(algorithm function object)