From cppreference.com
Defined in header
Call signature
template<std::destructibleT>constexprvoiddestroy_at(T*p)noexcept;(since C++20)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
(informally known as niebloids), that is:
Explicit template argument lists cannot be specified when calling any of them.
None of them are visible to
.
When any of them are found by
as the name to the left of the function-call operator,
is inhibited.
Parameters
p - a pointer to the object to be destroyed Possible implementation
structdestroy_at_fn{template<std::destructibleT>constexprvoidoperator()(T*p)constnoexcept{ifconstexpr(std::is_array_v<T>)for(auto&elem:*p)operator()(std::addressof(elem));elsep->~T();}};inlineconstexprdestroy_at_fndestroy_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
e, the argument p must point to an object whose lifetime began within the evaluation of e.
Example
Demonstrates how to use ranges::destroy_at to destroy a contiguous sequence of elements.
Run this code
#include<iostream>#include<memory>#include<new>structTracer{intvalue;~Tracer(){std::cout<<value<<" destructed\n";}};intmain(){alignas(Tracer)unsignedcharbuffer[sizeof(Tracer)*4];for(inti=0;i<4;++i)new(buffer+sizeof(Tracer)*i)Tracer{i};// manually construct objectsautoptr=std::launder(reinterpret_cast<Tracer*>(buffer));for(inti=0;i<4;++i)std::ranges::destroy_at(ptr+i);}Output:
0 destructed 1 destructed 2 destructed 3 destructed See also