std::ranges::destroy_at - cppreference.com

From cppreference.com

Defined in header

<memory>

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

algorithm function objects

(informally known as niebloids), that is:

Explicit template argument lists cannot be specified when calling any of them.

None of them are visible to

argument-dependent lookup

.

When any of them are found by

normal unqualified lookup

as the name to the left of the function-call operator,

argument-dependent lookup

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

constant expression

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