std::experimental::propagate_const
From cppreference.com
< cpp | experimental
| ヘッダ <experimental/propagate_const> で定義 |
||
| template< class T > class propagate_const; |
(Library Fundamentals TS v2) | |
std::experimental::propagate_constは、ポインタおよびポインタライクなオブジェクトのためのconst伝播ラッパーです。その名の通り、constなアクセスパスを通じてアクセスされた場合、ラップされたポインタをconstへのポインタとして扱います。
このクラスは、ラップされたポインタライクな型が対応する要件を満たす場合、ムーブ構築可能 (MoveConstructible) と ムーブ代入可能 (MoveAssignable) の要件を満たしますが、propagate_constは コピー構築可能 (CopyConstructible) でも コピー代入可能 (CopyAssignable) でもありません。
| 型要件 | ||
-Tは、以下で指定されるように、cv修飾されていないオブジェクトへのポインタ型、またはcv修飾されていないポインタライクなクラス型でなければなりません。 |
目次 |
[編集] ポインタライクなクラス型に対する要件
Tがクラス型である場合、このサブセクションの要件を満たさなければなりません。
以下を考えます。
-
t、型Tの変更可能な左辺値 (lvalue) 式。 -
ct、tと同じオブジェクトを指す型const Tの左辺値 (C++17以降のstd::as_const(t)と等価)。 -
element_type、オブジェクト型。
以下の式は有効であり、指定された効果を持たなければなりません。
| Expression | 戻り値の型 | 事前条件 | 操作的意味論 |
|---|---|---|---|
| t.get() | element_type* | ||
| ct.get() | element_type* または const element_type* | t.get() == ct.get() | |
| *t | element_type& | t.get() != nullptr | *tは*(t.get())と同じオブジェクトを参照する |
| *ct | element_type& または const element_type& | ct.get() != nullptr | *ctは*(ct.get())と同じオブジェクトを参照する |
| t.operator->() | element_type* | t.get() != nullptr | t.operator->() == t.get() |
| ct.operator->() | element_type* または const element_type* | ct.get() != nullptr | ct.operator->() == ct.get() |
| (bool)t | bool | (bool)tはt.get() != nullptrと等価である | |
| (bool)ct | bool | (bool)ctはct.get() != nullptrと等価である |
さらに、Tとconst Tは、文脈的にboolに変換可能でなければなりません。
加えて、Tがelement_type*に暗黙的に変換可能である場合、(element_type*)tはt.get()と等しくなければなりません。同様に、const Tがconst element_type*に暗黙的に変換可能である場合、(const element_type*)ctはct.get()と等しくなければなりません。
[編集] メンバ型
| メンバ型 | 定義 |
| element_type | std::remove_reference_t<decltype(*std::declval<T&>())>、Tが指すオブジェクトの型 |
[編集] メンバ関数
新しいpropagate_constを構築する(公開メンバ関数) | |
| (デストラクタ) (暗黙的に宣言) |
propagate_constを破棄し、含まれるポインタを破棄する(公開メンバ関数) |
propagate_constオブジェクトに代入する(公開メンバ関数) | |
| ラップされたポインタを交換する (公開メンバ関数) | |
監視 | |
| ラップされたポインタが指すオブジェクトへのポインタを返す (公開メンバ関数) | |
| ラップされたポインタがヌルかどうかをチェックする (公開メンバ関数) | |
| ラップされたポインタを間接参照する (公開メンバ関数) | |
| ポインタへの暗黙の変換関数 (公開メンバ関数) | |
[編集] 非メンバ関数
他のpropagate_const、他のポインタ、またはnullptrと比較する(関数テンプレート) | |
swapアルゴリズムを特殊化する(関数テンプレート) | |
| ラップされたポインタライクなオブジェクトへの参照を取得する (関数テンプレート) |
[編集] ヘルパークラス
propagate_constのハッシュサポート(クラステンプレートの特殊化) | |
propagate_constのための標準比較関数オブジェクトの特殊化(クラステンプレートの特殊化) |
[編集] 例
このコードを実行
#include <experimental/propagate_const> #include <iostream> #include <memory> struct X { void g() const { std::cout << "X::g (const)\n"; } void g() { std::cout << "X::g (non-const)\n"; } }; struct Y { Y() : m_propConstX(std::make_unique<X>()), m_autoPtrX(std::make_unique<X>()) {} void f() const { std::cout << "Y::f (const)\n"; m_propConstX->g(); m_autoPtrX->g(); } void f() { std::cout << "Y::f (non-const)\n"; m_propConstX->g(); m_autoPtrX->g(); } std::experimental::propagate_const<std::unique_ptr<X>> m_propConstX; std::unique_ptr<X> m_autoPtrX; }; int main() { Y y; y.f(); const Y cy; cy.f(); }
出力
Y::f (non-const) X::g (non-const) X::g (non-const) Y::f (const) X::g (const) X::g (non-const)
[編集] 欠陥報告
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| LWG 3136 | LFTSv2 | int* const、void*、またはconst PtrLikeのような無意味なTが許可されていた |
不許可になった |