std::ranges::uninitialized_value_construct
cppreference.net에서
| 헤더 <memory>
|
||
| 에 정의됨 |
||
template< /*nothrow-forward-iterator*/ I, /*nothrow-sentinel-for*/<I> S >
requires std::default_initializable<std::iter_value_t<I>>
I uninitialized_value_construct( I first, S last );
|
호출 시그니처 | (1) (C++20부터) |
template< /*nothrow-forward-range*/ R >
requires std::default_initializable<ranges::range_value_t<R>>
ranges::borrowed_iterator_t<R>
uninitialized_value_construct( R&& r );
|
(constexpr since C++26) | (2) (C++20부터) |
template< /*execution-policy*/ Ep, /*nothrow-random-access-iterator*/ I,
/*nothrow-sized-sentinel-for*/<I> S >
requires std::default_initializable<std::iter_value_t<I>>
I uninitialized_value_construct( Ep&& policy, I first, S last );
|
(constexpr since C++26) | (3) |
template< /*execution-policy*/ Ep, /*nothrow-sized-random-access-range*/ R >
requires std::default_initializable<ranges::range_value_t<R>>
ranges::borrowed_iterator_t<R>
uninitialized_value_construct( Ep&& policy, R&& r );
|
(C++26부터) | (4) |
(C++26부터)/*execution-policy*/의 정의는 이 페이지를, 기타 설명 전용 개념의 정의는 이 페이지를 참고하십시오.
1) 다음과 같이
[first, last) 목적지 범위의 요소들을 값 초기화(value-initialization)로 생성합니다:
for (; first != last; ++first)
::new (voidify(*first))
std::remove_reference_t<std::iter_reference_t<I>>();
return first;
초기화 중 예외가 발생하면, 이미 생성된 객체들은 지정되지 않은 순서로 파괴됩니다.
2) (1)과 동일하지만,
r을 목적지 범위로 사용합니다.3,4) (1,2)과 동일하지만,
policy에 따라 실행됩니다.이 페이지에 설명된 함수 유사 개체들은 알고리즘 함수 객체입니다 (비공식적으로 니블로이드(niebloids)라고 함). 즉:
- 이들 중 하나를 호출할 때 명시적 템플릿 인자 목록을 지정할 수 없습니다.
- 이들 중 어느 것도 인자 종속 조회(argument-dependent lookup)에 보이지 않습니다.
- 이들 중 하나가 일반 비한정 조회(normal unqualified lookup)에 의해 함수 호출 연산자의 왼쪽 이름으로 발견되면, 인자 종속 조회가 억제됩니다.
매개변수
| first, last | - | 값 초기화할 범위의 요소를 정의하는 반복자-센티널 쌍 |
| r | - | 값 초기화할 요소들의 범위 |
| policy | - | 사용할 실행 정책 |
반환값
위에서 설명한 바와 같습니다.
예외
대상 범위의 요소를 생성하는 중에 발생한 모든 예외.
3,4) 실행 과정 중:
- 병렬화에 필요한 임시 메모리 자원을 사용할 수 없는 경우, std::bad_alloc이 발생됩니다.
- 알고리즘 인수를 통해 객체에 접근하는 중에 처리되지 않은 예외가 발생하면, 동작은 실행 정책에 따라 결정됩니다 (표준 정책의 경우, std::terminate가 호출됩니다).
참고
구현은 범위의 값 유형이 ranges::uninitialized_value_construct (예: ranges::fill 사용)인 경우 CopyAssignable TrivialType인 경우 효율성을 향상시킬 수 있습니다.
| 기능-테스트 매크로 | 값 | 표준 | 기능 |
|---|---|---|---|
__cpp_lib_parallel_algorithm |
202506L |
(C++26) | 병렬 범위 알고리즘 |
__cpp_lib_raw_memory_algorithms |
202411L |
(C++26) | constexpr 전문화된 <memory> 알고리즘을 위한, (1,2)
|
가능한 구현
struct uninitialized_value_construct_fn
{
template</*nothrow-forward-iterator*/ I, /*nothrow-sentinel-for*/<I> S>
requires std::value_initializable<std::iter_value_t<I>>
constexpr I operator()(I first, S last) const
{
using value_type = std::remove_reference_t<std::iter_reference_t<I>>;
if constexpr (std::is_trivially_default_constructible_v<value_type>)
return ranges::fill(first, last, ValueType());
I rollback{first};
try
{
for (; !(first == last); ++first)
::new (static_cast<void*>(std::addressof(*first))) value_type();
return first;
}
catch (...) // rollback: destroy constructed elements
{
for (; rollback != first; ++rollback)
ranges::destroy_at(std::addressof(*rollback));
throw;
}
}
template</*nothrow-forward-range*/ R>
requires std::default_initializable<ranges::range_value_t<R>>
constexpr ranges::borrowed_iterator_t<R> operator()(R&& r) const
{
return (*this)(ranges::begin(r),
ranges::next(ranges::begin(r), ranges::end(r)));
}
};
inline constexpr uninitialized_value_construct_fn uninitialized_value_construct{};
|
예제
이 코드 실행하기
#include <iostream>
#include <memory>
#include <string>
int main()
{
struct S { std::string m{"▄▀▄▀▄▀▄▀"}; };
constexpr int n{4};
alignas(alignof(S)) char out[n * sizeof(S)];
try
{
auto first{reinterpret_cast<S*>(out)};
auto last{first + n};
std::ranges::uninitialized_value_construct(first, last);
auto count{1};
for (auto it{first}; it != last; ++it)
std::cout << count++ << ' ' << it->m << '\n';
std::ranges::destroy(first, last);
}
catch (...)
{
std::cout << "Exception!\n";
}
// For scalar types, uninitialized_value_construct
// zero-fills the given uninitialized memory area.
int v[]{0, 1, 2, 3};
std::cout << ' ';
for (const int i : v)
std::cout << ' ' << static_cast<char>(i + 'A');
std::cout << "\n ";
std::ranges::uninitialized_value_construct(std::begin(v), std::end(v));
for (const int i : v)
std::cout << ' ' << static_cast<char>(i + 'A');
std::cout << '\n';
}
출력:
1 ▄▀▄▀▄▀▄▀
2 ▄▀▄▀▄▀▄▀
3 ▄▀▄▀▄▀▄▀
4 ▄▀▄▀▄▀▄▀
A B C D
A A A A
참고 항목
| 초기화되지 않은 메모리 영역에 시작점과 개수로 정의된 위치에 객체를 값 초기화로 생성합니다 (알고리즘 함수 객체) | |
| 초기화되지 않은 메모리 영역에 범위로 정의된 위치에 객체를 기본 초기화로 생성합니다 (알고리즘 함수 객체) | |
| 초기화되지 않은 메모리 영역에 시작점과 개수로 정의된 위치에 객체를 기본 초기화로 생성합니다 (알고리즘 함수 객체) | |
| 초기화되지 않은 메모리 영역에 범위로 정의된 위치에 객체를 값 초기화로 생성합니다 (함수 템플릿) |