std::ranges::destroy — cppreference.com
Материал из cppreference.com
<tbody> </tbody>
| Определено в заголовочном файле |
||
| Сигнатура вызова |
||
|
|
(1) | (начиная с C++20) |
|
|
(2) | (начиная с C++20) |
1) Уничтожает объекты в диапазоне [first, last), как если бы
for (; first != last; ++first) std::ranges::destroy_at(std::addressof(*first)); return first;
2) То же, что и (1), но использует r в качестве исходного диапазона, как если бы использовались ranges::begin(r) в качестве first и ranges::end(r) в качестве last.
Функционально-подобные объекты, описанные на этой странице, являются ниблоидами, то есть:
- Явные списки аргументов шаблона не могут быть указаны при вызове любого из них.
- Ни один из них не виден для поиска, зависящего от аргумента.
- Когда какой-либо из них обнаруживается обычным неквалифицированным поиском по имени слева от оператора вызова функции, поиск, зависящий от аргумента запрещён.
На практике они могут быть реализованы как функциональные объекты или со специальными расширениями компилятора.
Параметры
| first, last | — | пара итератор-ограничитель, обозначающая диапазон элементов для уничтожения |
| r | — | диапазон для уничтожения |
Возвращаемое значение
Итератор при сравнении равный last.
Сложность
Линейная по расстоянию между first и last.
Возможная реализация
struct destroy_fn { template<итератор-ввода-без-исключения I, ограничитель-без-исключения-для<I> S> requires std::destructible<std::iter_value_t<I>> constexpr I operator()(I first, S last) const noexcept { for (; first != last; ++first) std::ranges::destroy_at(std::addressof(*first)); return first; } template<входной-диапазон-без-исключения R> requires std::destructible<std::ranges::range_value_t<R>> constexpr std::ranges::borrowed_iterator_t<R> operator()(R&& r) const noexcept { return operator()(std::ranges::begin(r), std::ranges::end(r)); } }; inline constexpr destroy_fn destroy{};
Пример
В следующем примере показано, как использовать ranges::destroy для уничтожения непрерывной последовательности элементов.
#include <iostream> #include <memory> #include <new> struct Tracer { int value; ~Tracer() { std::cout << value << " уничтожен\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}; //создаём объекты вручную auto ptr = std::launder(reinterpret_cast<Tracer*>(buffer)); std::ranges::destroy(ptr, ptr + 8); }
Вывод:
0 уничтожен 1 уничтожен 2 уничтожен 3 уничтожен 4 уничтожен 5 уничтожен 6 уничтожен 7 уничтожен