6

関数から右辺値参照を返すことが危険である理由を理解していることから、次のコードが原因です。

T&& f(T&& x) { do_something_to_T(x); return static_cast<T&&>(x); }
T f(const T& x) { T x2 = x; do_something_to_T(x2); return x2; }
T&& y = f(T());

これはy、未定義のダングリング参照として残ります。

しかし、なぜ上記のコードがコンパイルされるのか理解できませんか? 右辺値参照を別の右辺値参照に割り当てる正当な理由はありますか? 右辺値は、大まかに言えば「一時的」であると想定されていませんか?つまり、式の最後で無効にされますか? それらを割り当てることができることは、私にはばかげているようです。

4

1 に答える 1

10

右辺値は、大まかに言えば「一時的」であると想定されていませんか?つまり、式の最後で無効にされますか?

いいえ、そうではないです。

あなたの function を考えるとf、これは同様に合法です:

T t{};
T&& y = f(std::move(t));

これは完全に有効な C++11 コードです。また、何が起こるかは明確に定義されています。

コードが定義されていない唯一の理由は、一時的なものを渡すためです。ただし、右辺値参照は一時的である必要はありません。

もう少し詳しく説明すると、r-value 参照は、概念的には、特定の操作を実行しても問題ないと見なされる値への参照です。

C++11 では、R 値参照は非常に慎重に指定されています。左辺値参照は、キャストなどを必要とせずに任意の非一時値にバインドできます。

T t{};
T &y = t;

右辺値参照は、一時的またはその他の "xvalue" (近い将来確実になくなるオブジェクト) にのみ暗黙的にバインドできます。

T &&x = T{};
T &&no = t; //Fail.

右辺値参照を非 xvalue にバインドするには、明示的なキャストを行う必要があります。C++11 がこのキャストを綴る方法は、次のことを示していますstd::move

T &&yes = std::move(t);

私が言っていた「特定の操作」は「移動」でした。オブジェクトからの移動は、次の 2 つの条件だけで問題ありません。

  1. とにかく消えていきます。IE: 一時的なもの。
  2. ユーザーは明示的にそこから移動するように言いました。

これらは、右辺値参照が何かにバインドできる唯一の 2 つのケースです。

右辺値参照が存在する理由は、正確に 2 つあります。移動セマンティクスをサポートするためと、完全な転送をサポートするためです (これには、ファンキーなキャスト メカニズムをフックできる新しい参照型が必要であり、移動セマンティクスの可能性もあります)。したがって、これら 2 つの操作のいずれかを行っていない場合、 a を使用する理由&&は疑わしいものになります。

于 2012-02-29T05:39:18.263 に答える