Skip to main content

std::construct_at() algorithm

// (1)
template< class T, class... Args >
constexpr T* construct_at( T* p, Args&&... args );

Creates a T object initialized with arguments args... at given address p.

return ::new (static_cast<void*>(p)) T(std::forward<Args>(args)...);

Except that construct_at may be used in evaluation of constant expressions.

When construct_at is called in the evaluation of some constant expression e, the argument p must point to either storage obtained by std::allocator<T>::allocate or an object whose lifetime began within the evaluation of e.

Overload Resolution

Participates in overload resolution only if ::new(std::declval<void*>()) T(std::declval<Args>()...) is well-formed in unevaluated context.

Parameters

p

Pointer to the uninitialized storage on which a T object will be constructed.

args..

Args to initialize the object with.

Return value

p

(none)

Complexity

O(1)

Exceptions

(none)

Possible implementation

ranges::construct_at(1)
struct construct_at_fn
{
template<class T, class...Args>
requires
requires (void* vp, Args&&... args)
{ ::new (vp) T(static_cast<Args&&>(args)...); }
constexpr T* operator()(T* p, Args&&... args) const
{
return std::construct_at(p, static_cast<Args&&>(args)...);
}
};

inline constexpr construct_at_fn construct_at{};

Notes

std::ranges::construct_at behaves exactly same as std::construct_at, except that it is invisible to argument-dependent lookup.

Examples

Main.cpp
#include <iostream>
#include <memory>

struct S
{
int x;
float y;
double z;

S(int x, float y, double z) : x{x}, y{y}, z{z} { std::cout << "S::S();\n"; }

~S() { std::cout << "S::~S();\n"; }

void print() const
{
std::cout << "S { x=" << x << "; y=" << y << "; z=" << z << "; };\n";
}
};

int main()
{
alignas(S) unsigned char buf[sizeof(S)];

S* ptr = std::ranges::construct_at(reinterpret_cast<S*>(buf), 42, 2.71828f, 3.1415);
ptr->print();

std::ranges::destroy_at(ptr);
}
Output
S::S();
S { x=42; y=2.71828; z=3.1415; };
S::~S();
This article originates from this CppReference page. It was likely altered for improvements or editors' preference. Click "Edit this page" to see all changes made to this document.
Hover to see the original license.

std::construct_at() algorithm

// (1)
template< class T, class... Args >
constexpr T* construct_at( T* p, Args&&... args );

Creates a T object initialized with arguments args... at given address p.

return ::new (static_cast<void*>(p)) T(std::forward<Args>(args)...);

Except that construct_at may be used in evaluation of constant expressions.

When construct_at is called in the evaluation of some constant expression e, the argument p must point to either storage obtained by std::allocator<T>::allocate or an object whose lifetime began within the evaluation of e.

Overload Resolution

Participates in overload resolution only if ::new(std::declval<void*>()) T(std::declval<Args>()...) is well-formed in unevaluated context.

Parameters

p

Pointer to the uninitialized storage on which a T object will be constructed.

args..

Args to initialize the object with.

Return value

p

(none)

Complexity

O(1)

Exceptions

(none)

Possible implementation

ranges::construct_at(1)
struct construct_at_fn
{
template<class T, class...Args>
requires
requires (void* vp, Args&&... args)
{ ::new (vp) T(static_cast<Args&&>(args)...); }
constexpr T* operator()(T* p, Args&&... args) const
{
return std::construct_at(p, static_cast<Args&&>(args)...);
}
};

inline constexpr construct_at_fn construct_at{};

Notes

std::ranges::construct_at behaves exactly same as std::construct_at, except that it is invisible to argument-dependent lookup.

Examples

Main.cpp
#include <iostream>
#include <memory>

struct S
{
int x;
float y;
double z;

S(int x, float y, double z) : x{x}, y{y}, z{z} { std::cout << "S::S();\n"; }

~S() { std::cout << "S::~S();\n"; }

void print() const
{
std::cout << "S { x=" << x << "; y=" << y << "; z=" << z << "; };\n";
}
};

int main()
{
alignas(S) unsigned char buf[sizeof(S)];

S* ptr = std::ranges::construct_at(reinterpret_cast<S*>(buf), 42, 2.71828f, 3.1415);
ptr->print();

std::ranges::destroy_at(ptr);
}
Output
S::S();
S { x=42; y=2.71828; z=3.1415; };
S::~S();
This article originates from this CppReference page. It was likely altered for improvements or editors' preference. Click "Edit this page" to see all changes made to this document.
Hover to see the original license.