namespace std {
template <class T, class D = default_delete<T>>
class hazard_pointer_obj_base;
}
概要
hazard_pointer_obj_baseは、ハザードポインタで保護する対象とする型の基底クラスである。
使用するときは、型Tでhazard_pointer_obj_baseを公開かつ非仮想で継承した上で、派生クラスTをhazard_pointer_obj_baseのテンプレート引数にする(CRTP)。
struct Data : std::hazard_pointer_obj_base<Data> {
// ...
};
型Tが、ちょうど1つのpublicかつ非仮想な基底クラスhazard_pointer_obj_base<T, D>をもち、ほかにhazard_pointer_obj_base<T2, D2>型の基底クラスをもたないとき、その型は「ハザードポインタで保護可能な型」(hazard-protectable type)となる。
テンプレートパラメータDは、オブジェクトの削除方法を指定する関数オブジェクト型であり、既定ではdefault_delete<T>(delete式による破棄)となる。
適格要件
Tは不完全型でもよいが、特殊化されたhazard_pointer_obj_baseのメンバが参照されるまでに完全型とすること。Dは関数オブジェクト型であり、D型の値dとT*型の値ptrに対して式d(ptr)が有効であること。D型は要件 Cpp17DefaultConstructible および Cpp17MoveAssignable を満たすこと。
メンバ関数
| 名前 | 説明 | 対応バージョン |
|---|---|---|
(constructor) |
コンストラクタ | C++26 |
(destructor) |
デストラクタ | C++26 |
operator= |
代入演算子 | C++26 |
retire |
オブジェクト回収をスケジュールする | C++26 |
備考
- このクラステンプレートに対する特殊化を追加するプログラムの動作は未定義である。
例
#include <hazard_pointer>
#include <atomic>
#include <print>
struct Data : std::hazard_pointer_obj_base<Data> {
int value;
explicit Data(int v) : value(v) {}
};
// 共有データを指すポインタ
std::atomic<Data*> data{new Data(1)};
int main()
{
// 読み込み側: ハザードポインタで保護してから参照する
std::hazard_pointer h = std::make_hazard_pointer();
Data* p = h.protect(data);
std::println("{}", p->value);
// 更新側: 差し替えて古いオブジェクトを回収予約する
Data* old = data.exchange(new Data(2));
old->retire(); // 保護が解除されてから回収される
// 最後に残ったオブジェクトも回収予約する
// (取り外したオブジェクトを retire し忘れると回収されずリークするので注意)
data.load()->retire();
}
出力
1
バージョン
言語
- C++26
処理系
- Clang: ??
- GCC: ??
- ICC: ??
- Visual C++: ??
関連項目
参照
- P2530R3 Hazard Pointers for C++26
- C++26で追加された