8

次のコードを書くと:

#include <iostream>

using namespace std;

int main()
{
  cout << &(int &&)123 << endl;
  return 0;
}

次にg++文句を言う:

foo.cc: In function ‘int main()’:
foo.cc:7:20: error: taking address of xvalue (rvalue reference)

わかりました。rvalues、lvalues、xvalues、glvalues、prvaluesとは何ですか?xvalueは、「期限切れ」になることを意味します。これは理にかなっています。しかし今、私がこれを行うと:

#include <iostream>

using namespace std;

int main()
{
  const int &x = (int &&)123;
  cout << &x << endl;
  return 0;
}

これは問題なく「機能」し、アドレスを出力します。だから、私はいくつかの質問があります:

  1. 値が期限切れになりそうな場合、なぜそれを参照できるのですか?参照は元のオブジェクトを存続させません(右?)。
  2. そのような参照は未定義の動作をもたらしますか?たとえば、破壊された可能性のあるオブジェクトを参照しているためですか?

一般に、右辺値参照の存続期間を知る方法はありますか?

4

2 に答える 2

10

おそらく私は一人ですが、これは安全ではないと思います。

const int &x = (int &&)123;

有効期間延長ルールは、一時オブジェクトを直接参照する式によって参照が初期化される場合にのみ適用されます。つまり、には「一時的」属性が含まれている必要があります。を省略した場合(int&&)、参照にバインドするために、コンパイラーは、値によって初期化されてから有効期間の延長が適用される一時オブジェクトを参照するprvalue式を暗黙的に作成し123ます。

ただし、間に右辺値参照を混在させると、コンパイラーは、コンパイル時に、参照されるオブジェクトの存続期間を延長するかどうかを知る方法がありません。

int a = 0;
const int &x = ((rand() == 42) ? (int&&)123 : (int&&)a);

したがって、ぶら下がっている参照を評価するため(アドレスを取得するためだけであっても)、コードの動作は未定義であると思います。

于 2012-02-27T22:09:11.460 に答える
2

12.2項の4-5項は、2番目の例では寿命延長されると述べています

完全な式の終わりとは異なる時点で一時的なものが破棄される2つのコンテキストがあります。..。

2番目のコンテキストは、参照が一時的なものにバインドされている場合です。参照がバインドされている一時オブジェクト、または参照がバインドされているサブオブジェクトの完全なオブジェクトである一時オブジェクトは、次の場合を除いて、参照の存続期間中存続し
ます(ここでは例外は適用されません)。

于 2012-02-27T16:21:43.327 に答える