[解決済み】std::launderの目的は何ですか?
質問
P0137
は、関数テンプレートを導入しています。
std::launder
また、ユニオン、ライフタイム、ポインタに関するセクションで、標準に多くの変更を加えています。
この論文が解決しようとしている問題は何なのか?注意しなければならない言語の変更は何なのか?そして、私たちは何をすればいいのか?
launder
を行うのでしょうか?
どのように解決するのですか?
std::launder
という名前は、何のためにあるのかが分かっていれば、適切な名前だと思います。これは
メモリロンダリング
.
論文にある例を考えてみましょう。
struct X { const int n; };
union U { X x; float f; };
...
U u = {{ 1 }};
このステートメントは、集約の初期化を行い
U
で
{1}
.
なぜなら
n
は
const
という変数がある場合、コンパイラは自由に
u.x.n
とする。
常に
は1である。
では、こうするとどうなるか。
X *p = new (&u.x) X {2};
なぜなら
X
は些細なことなので、新しいオブジェクトを作成する前に古いオブジェクトを破壊する必要はありません。新しいオブジェクトはその
n
のメンバは2です。
では、教えてください......どうなるんですか?
u.x.n
を返しますか?
明らかな答えは、2でしょう。しかし、それは間違っています。なぜなら、コンパイラは、本当に
const
変数(単に
const&
でなく、オブジェクト変数
宣言
const
)
は変わらない
. でも、変えただけなんです。
[基本.生活]/8
は、新しく作成されたオブジェクトに、古いオブジェクトの変数/ポインタ/参照を通じてアクセスしてもよい状況を明示しています。そして
const
メンバは失格要因の一つである。
では...どうすれば
u.x.n
を正しく使うことができるでしょうか?
メモリロンダリングが必要なんです。
assert(*std::launder(&u.x.n) == 2); //Will be true.
マネーロンダリングは、どこからお金を手に入れたか追跡されるのを防ぐために使われます。メモリロンダリングは コンパイラ オブジェクトの入手先を追跡できないようにすることで、もはや適用されないかもしれない最適化を回避させる。
もうひとつの欠点は、オブジェクトの型を変更した場合です。
std::launder
はここでも役に立ちます。
aligned_storage<sizeof(int), alignof(int)>::type data;
new(&data) int;
int *p = std::launder(reinterpret_cast<int*>(&data));
[基本.生活]/8
は、古いオブジェクトのストレージに新しいオブジェクトを割り当てた場合、古いオブジェクトへのポインタを通じて新しいオブジェクトにアクセスできないことを教えてくれています。
launder
を使えば、それを回避することができます。
関連
-
[解決済み】C++でint型に無限大を設定する
-
[解決済み】クラステンプレートの引数リストがない
-
[解決済み】C++の余分な資格エラー
-
[解決済み] explicit キーワードの意味は?
-
[解決済み] using namespace std;」はなぜバッドプラクティスだと言われるのですか?
-
[解決済み] ルール・オブ・スリーとは?
-
[解決済み] コピーアンドスワップ慣用句とは?
-
[解決済み] ムーブセマンティクスとは何ですか?
-
[解決済み] template "と "typename "キーワードはどこに、なぜ入れなければならないのですか?
-
[解決済み】C/C++の"-->"演算子とは何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] テスト
-
[解決済み】C++エラー。アーキテクチャ x86_64 に対して未定義のシンボル
-
[解決済み】C++でint型に無限大を設定する
-
[解決済み】抽象クラス型の無効なnew-expression
-
[解決済み】IntelliSense:オブジェクトに、メンバー関数と互換性のない型修飾子がある
-
[解決済み】C++の変数はイニシャライザーを持っているが、不完全な型?
-
[解決済み】C++プログラムでのコンソールの一時停止
-
[解決済み】クラステンプレートの使用にはテンプレート引数リストが必要です
-
[解決済み】指定範囲内の乱数で配列を埋める(C++)
-
[解決済み】変数やフィールドがvoid宣言されている