Skip to main content

std::ranges::destroy_at() algorithm

// (1)
template< std::destructible T >
constexpr void destroy_at( T* p ) noexcept;

If T is not an array type, calls the destructor of the object pointed to by p, as if by p->~T().

Otherwise, recursively destroys elements of *p in order, as if by calling std::destroy(std::begin(*p), std::end(*p)).

The function-like entities described on this page are niebloids.

Parameters

p

A pointer to the object to be destroyed.

Return value

(none)

Complexity

O(1)

Exceptions

The exception thrown on construction of the elements in the destination range, if any.

Possible implementation

destroy_at(1)
struct destroy_at_fn
{
template<std::destructible T>
constexpr void operator()(T *p) const noexcept
{
if constexpr (std::is_array_v<T>)
for (auto &elem : *p)
operator()(std::addressof(elem));
else
p->~T();
}
};

inline constexpr destroy_at_fn destroy_at{};

Notes

destroy_at deduces the type of object to be destroyed and hence avoids writing it explicitly in the destructor call.

When destroy_at is called in the evaluation of some constant expression e, the argument p must point to an object whose lifetime began within the evaluation of e.

Examples

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

struct Tracer
{
int value;
~Tracer() { std::cout << value << " destructed\n"; }
};

int main()
{
alignas(Tracer) unsigned char buffer[sizeof(Tracer) * 8];

for (int i = 0; i < 8; ++i)
new(buffer + sizeof(Tracer) * i) Tracer{i}; //manually construct objects

auto ptr = std::launder(reinterpret_cast<Tracer*>(buffer));

std::ranges::destroy_at(ptr, ptr + 8);
}
Output
0 destructed
1 destructed
2 destructed
3 destructed
4 destructed
5 destructed
6 destructed
7 destructed
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::ranges::destroy_at() algorithm

// (1)
template< std::destructible T >
constexpr void destroy_at( T* p ) noexcept;

If T is not an array type, calls the destructor of the object pointed to by p, as if by p->~T().

Otherwise, recursively destroys elements of *p in order, as if by calling std::destroy(std::begin(*p), std::end(*p)).

The function-like entities described on this page are niebloids.

Parameters

p

A pointer to the object to be destroyed.

Return value

(none)

Complexity

O(1)

Exceptions

The exception thrown on construction of the elements in the destination range, if any.

Possible implementation

destroy_at(1)
struct destroy_at_fn
{
template<std::destructible T>
constexpr void operator()(T *p) const noexcept
{
if constexpr (std::is_array_v<T>)
for (auto &elem : *p)
operator()(std::addressof(elem));
else
p->~T();
}
};

inline constexpr destroy_at_fn destroy_at{};

Notes

destroy_at deduces the type of object to be destroyed and hence avoids writing it explicitly in the destructor call.

When destroy_at is called in the evaluation of some constant expression e, the argument p must point to an object whose lifetime began within the evaluation of e.

Examples

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

struct Tracer
{
int value;
~Tracer() { std::cout << value << " destructed\n"; }
};

int main()
{
alignas(Tracer) unsigned char buffer[sizeof(Tracer) * 8];

for (int i = 0; i < 8; ++i)
new(buffer + sizeof(Tracer) * i) Tracer{i}; //manually construct objects

auto ptr = std::launder(reinterpret_cast<Tracer*>(buffer));

std::ranges::destroy_at(ptr, ptr + 8);
}
Output
0 destructed
1 destructed
2 destructed
3 destructed
4 destructed
5 destructed
6 destructed
7 destructed
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.