memory_construct_at
memory_construct_at (std::construct_at)
<memory> 헤더에 정의되어 있어요. 주어진 주소 location에 args 인자들로 초기화된 T 객체를 생성해요. std::allocator_traits::construct의 핵심 구현이자, placement new를 constexpr에서 쓸 수 있게 해주는 함수예요. C++20부터 도입됐어요.
출처: cppreference
본문
template< class T, class... Args >
constexpr T* construct_at( T* location, Args&&... args );
(C++20부터)
주어진 주소 location에 args 인자들로 초기화된 T 객체를 생성해요. 다음과 동등해요.
if constexpr (std::is_array_v<T>)
return ::new (voidify(*location)) T[1]();
else
return ::new (voidify(*location)) T(std::forward<Args>(args)...);
다만 construct_at은 상수 표현식의 평가에서 쓸 수 있어요. (C++26 이전)
construct_at이 어떤 상수 표현식 expr의 평가에서 호출되면, location은 std::allocator<T>::allocate로 얻은 저장 공간이거나 expr의 평가 안에서 수명이 시작된 객체를 가리켜야 해요.
이 오버로드는 다음 조건이 모두 만족될 때만 오버로드 해석에 참여해요.
std::is_unbounded_array_v<T>가false예요.::new(std::declval<void*>()) T(std::declval<Args>()...)가 평가되지 않은 피연산자로 다뤄질 때 well-formed예요.
std::is_array_v<T>가 true이고 sizeof...(Args)가 0이 아니면 프로그램은 ill-formed예요.
매개변수
location:T객체가 구성될 초기화되지 않은 저장 공간에 대한 포인터args...: 초기화에 사용할 인자들
반환값
location.
예제
#include <bit>
#include <memory>
class S
{
int x_;
float y_;
double z_;
public:
constexpr S(int x, float y, double z) : x_(x), y_(y), z_(z) {}
// ...
};
constexpr S make()
{
// constexpr 문맥에서 placement new 대신 construct_at 사용
std::byte storage[sizeof(S)];
S* s = std::construct_at(reinterpret_cast<S*>(storage), 1, 2.0f, 3.0);
return *s;
}