7

C++11 標準の 12.2 では:

参照がバインドされている一時オブジェクト、または参照がバインドされているサブオブジェクトの完全なオブジェクトである一時オブジェクトは、次の例外を除き、参照の存続期間中持続します。

  1. コンストラクターの ctor-initializer (12.6.2) の参照メンバーへの一時的なバインドは、コンストラクターが終了するまで持続します。

  2. 関数呼び出し (5.2.2) の参照パラメーターへの一時的なバインドは、呼び出しを含む完全な式が完了するまで持続します。

  3. 関数 return ステートメント (6.6.3) の戻り値に一時的にバインドされているものの有効期間は延長されません。一時的なものは、return ステートメントの完全な式の最後で破棄されます。

  4. new-initializer (5.3.4) の参照への一時的なバインドは、new-initializer を含む完全な式が完了するまで持続します。

そして、標準の最後のケースの例があります:

struct S {
  int mi; 
  const std::pair<int,int>& mp;
}; 
S a { 1,{2,3} };  // No problem.
S* p = new S{ 1, {2,3} };  // Creates dangling reference

私にとっては、2. and 3.理にかなっていて同意しやすい. しかし、bebind の理由は何1. and 4.ですか? この例は私には悪に見えます。

4

3 に答える 3

2

主な要点は、参照の拡張は、有効期間が簡単かつ決定論的に決定できる場合にのみ発生するということです。この事実は、テンポラリーが作成されるコード行で可能な限り推測できます。

関数を呼び出すと、現在の行の末尾まで拡張されます。それは十分に長く、簡単に判断できます。

「スタック上」で自動ストレージ参照を作成すると、その自動ストレージ参照のスコープを決定論的に決定できます。一時的なものはその時点でクリーンアップできます。(基本的には匿名の自動格納変数を作成して一時格納します)

式では、new作成時点で静的に破壊点を決定することはできません。deleteが発生するたびです。一時オブジェクトを (場合によっては) 破棄したい場合delete、参照 "バイナリ" 実装は、以下ではなく、ポインターよりも複雑にする必要があります。参照先のデータを所有する場合もあれば、所有しない場合もあります。つまり、これはポインターとbool. そして C++ では、使用しないものに対して料金を支払う必要はありません。

newコンストラクターがスタック割り当てにあったかどうかがわからないため、コンストラクターにも同じことが当てはまります。したがって、有効期間の延長は、問題の行で静的に理解することはできません。

于 2014-02-20T22:27:07.133 に答える