次のコード行を検討してください。
new (p++) T();
コンストラクターT()
が例外をスローした場合、p
既にインクリメントされていることが保証されますか?
次のコード行を検討してください。
new (p++) T();
コンストラクターT()
が例外をスローした場合、p
既にインクリメントされていることが保証されますか?
5.3.4 [expr.new] から (n3242 から引用):
11 new-placement 構文は、割り当て関数に追加の引数を提供するために使用されます。使用された場合、オーバーロードの解決は、要求されたスペースの量 (最初の引数) と new-expression の new-placement 部分の式 (2 番目以降の引数) で構成される引数リストを組み立てることによって作成された関数呼び出しで実行されます。 .
したがって、新しい式では、関数呼び出しから割り当て関数が使用されます (これは理にかなっています)。すべての割り当て関数は、3.7.4.1 [basic.stc.dynamic.allocation] からの実装によって提供されるものを含む関数です。
1割り当て関数は、クラス メンバ関数またはグローバル関数でなければなりません。[...]
したがって、コンストラクターから例外がスローされるまでに、割り当てが行われ、関連する関数呼び出し式が完全に評価されます。
はい、インクリメントされることが保証されています。
演算子は、関数/メソッド呼び出しの単なる構文糖衣です。
new が演算子の上に特別な意味を持っているとは思わないので、同じでなければなりません。
したがって、すべてのパラメーターは、関数new
が呼び出される前に (シーケンス ポイントを使用して) 完全に評価されます。
標準がこの質問に直接/明示的に答えているとは思いません。ただし、暗黙のうちに、答えはイエスです。
特に、new の配置構文は、関数に渡される追加のパラメーターを指定する方法にすぎません。他の関数呼び出しと同様に、関数へのすべてのパラメーターを (不特定の順序で) 評価してから、関数内のコードを実行するまでの間にシーケンス ポイントがあります。p++
それは、あなたの意志が評価され、他の何かが起こる前にすべての副作用が適用されることを意味するはずです.
Placement new は、 という名前の単なる通常の関数operator new(size_t, void*)
です。2 番目の引数を返すだけです。
インクリメント演算子は次のことを行います。
したがって、p
インクリメントされることが保証されます。