std::ranges::destroy_at
ja.cppreference.net から
| ヘッダで定義 <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))を呼び出すことで再帰的に破棄します。
このページで説明される関数状のエンティティは アルゴリズム関数オブジェクト(通称 niebloid)です。すなわち:
- それらのいずれかを呼び出す際に、明示的なテンプレート引数リストを指定することはできません。
- それらは 引数依存の名前検索では見つかりません。
- それらのいずれかが 通常の非修飾名前検索によって関数呼び出し演算子の左側の名前として見つかった場合、引数依存の名前検索は抑制されます。
パラメータ
| 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) * 4];
for (int i = 0; i < 4; ++i)
new (buffer + sizeof(Tracer) * i) Tracer{i}; // manually construct objects
auto ptr = std::launder(reinterpret_cast<Tracer*>(buffer));
for (int i = 0; i < 4; ++i)
std::ranges::destroy_at(ptr + i);
}
出力:
0 destructed
1 destructed
2 destructed
3 destructed
関連項目
(C++20) |
範囲のオブジェクトを破棄する (アルゴリズム関数オブジェクト) |
(C++20) |
範囲内の指定された個数のオブジェクトを破棄する (アルゴリズム関数オブジェクト) |
(C++20) |
指定されたアドレスにオブジェクトを作成する (アルゴリズム関数オブジェクト) |
(C++17) |
指定されたアドレスのオブジェクトを破棄する (関数テンプレート) |