std::ranges::destroy_at
Определено в заголовочном файле <memory> |
||
|---|---|---|
| Подпись вызова | ||
template< std::destructible T > constexpr void destroy_at( T* p ) noexcept; |
(с C++20) |
Если T не является типом массива, вызывает деструктор объекта, на который указывает p, как если бы это делалось с помощью p->~T(). В противном случае рекурсивно уничтожает элементы *p в порядке, как если бы вызывался std::destroy(std::begin(*p), std::end(*p)).
Функциональные сущности, описанные на этой странице, являются niebloids, т.е.:
- Явные списки шаблонов аргументов не могут быть указаны при вызове любого из них.
- Ни один из них не виден для поиска зависимого от аргументов.
- Если любой из них найден обычным поиском без квалификации как имя слева от оператора вызова функции, поиск, зависимый от аргументов запрещён.
На практике они могут быть реализованы как объекты-функции или с помощью специальных расширений компилятора.
Параметры
| p | - | указатель на объект, который нужно уничтожить |
Возвращаемое значение
(нет)
Возможная реализация
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{}; |
Примечания
destroy_at выводит тип объекта, подлежащего уничтожению, и тем самым избегает явного написания его в вызове деструктора.
Когда destroy_at вызывается при вычислении некоторого постоянного выражения e, аргумент p должен указывать на объект, чья продолжительность жизни началась в ходе вычисления e.
Пример
Следующий пример демонстрирует, как использовать ranges::destroy_at для уничтожения последовательности элементов.
#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));
for (int i = 0; i < 8; ++i)
std::ranges::destroy_at(ptr + i);
}Вывод:
0 destructed 1 destructed 2 destructed 3 destructed 4 destructed 5 destructed 6 destructed 7 destructed
См. также
|
(C++20) |
уничтожает диапазон объектов (niebloid) |
|
(C++20) |
уничтожает заданное количество объектов в диапазоне (niebloid) |
|
(C++20) |
создаёт объект по заданному адресу (niebloid) |
|
(C++17) |
уничтожает объект по заданному адресу (функция-шаблон) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/memory/ranges/destroy_at