12

次のコード行を検討してください。

new (p++) T();

コンストラクターT()が例外をスローした場合、p既にインクリメントされていることが保証されますか?

4

5 に答える 5

8

5.3.4 [expr.new] から (n3242 から引用):

11 new-placement 構文は、割り当て関数に追加の引数を提供するために使用されます。使用された場合、オーバーロードの解決は、要求されたスペースの量 (最初の引数) と new-expression の new-placement 部分の式 (2 番目以降の引数) で構成される引数リストを組み立てることによって作成された関数呼び出しで実行されます。 .

したがって、新しい式では、関数呼び出しから割り当て関数が使用されます (これは理にかなっています)。すべての割り当て関数は、3.7.4.1 [basic.stc.dynamic.allocation] からの実装によって提供されるものを含む関数です。

1割り当て関数は、クラス メンバ関数またはグローバル関数でなければなりません。[...]

したがって、コンストラクターから例外がスローされるまでに、割り当てが行われ、関連する関数呼び出し式が完全に評価されます。

于 2011-06-27T18:16:13.687 に答える
4

はい、インクリメントされることが保証されています。

演算子は、関数/メソッド呼び出しの単なる構文糖衣です。
new が演算子の上に特別な意味を持っているとは思わないので、同じでなければなりません。

したがって、すべてのパラメーターは、関数newが呼び出される前に (シーケンス ポイントを使用して) 完全に評価されます。

于 2011-06-27T18:15:06.400 に答える
3

標準がこの質問に直接/明示的に答えているとは思いません。ただし、暗黙のうちに、答えはイエスです。

特に、new の配置構文は、関数に渡される追加のパラメーターを指定する方法にすぎません。他の関数呼び出しと同様に、関数へのすべてのパラメーターを (不特定の順序で) 評価してから、関数内のコードを実行するまでの間にシーケンス ポイントがあります。p++それは、あなたの意志が評価され、他の何かが起こる前にすべての副作用が適用されることを意味するはずです.

于 2011-06-27T18:15:26.713 に答える
0

Placement new は、 という名前の単なる通常の関数operator new(size_t, void*)です。2 番目の引数を返すだけです。

于 2011-06-27T18:14:20.647 に答える
-1

インクリメント演算子は次のことを行います。

  1. 古い値を内部コピーに保存します
  2. 1ずつ増加
  3. 古い値を返します
  4. 古い値のコピーを削除します

したがって、pインクリメントされることが保証されます。

于 2011-06-27T18:07:31.917 に答える