3

ボンネットの下にあるものをよく理解するために...質問はコメントとしてコード内にあります

   void test(int && val)
    {
        val=4;
    }//val is  destroyed here ?

int main()
{  
    int nb;
    test(std::move(nb));
    //undefined behavior if I reference here nb ?
    std::cout << nb;
    nb=5;
    std::cin.ignore();    
}
4

6 に答える 6

3

移動元の値は有効ですが、指定されていない状態のままです。これは基本的に、私の知る限り、任意の値が含まれている可能性がありますが、何らかの値が含まれている必要があり、それにアクセスすることは合法であり、定義された動作であることを意味します。

于 2011-07-28T21:39:17.393 に答える
3

何かへの右辺値参照が魔法のように値を移動するわけではないことを理解する必要があります。一時オブジェクトへの非 const 参照を取得できるようにするだけです。

この参照は、ここに一時的なものがないため、通常の参照と変わらない例です。「行動」を起こすのはあなたです。

たとえば、値が の場合に int が空であると定義し0、右辺値参照を受け取り、それを消費して渡された値を に設定する関数を作成すると0、前の値が int から「移動」されます。この関数を呼び出した後、含まれます0。しかし、それはあなたがそのように定義したからです。

int の場合、これはあまり意味がありませんが、メモリの大きな部分へのポインタを扱っていると想像してください。

于 2011-07-28T20:40:58.247 に答える
1

関数内から実際に移動することはないため、これは未定義の動作ではありませんvalstd::move単にnb右辺値に変わります。これは実際には、あいまいな のオーバーロードがある場合にのみ意味がありますtest

于 2011-07-28T20:14:01.947 に答える
0

ほとんどの場合、右辺値参照は、コピーのコストを気にする新しいクラスを作成していて、移動コンストラクターを作成したい場合に役立ちます。

他の誰かのムーブ コンストラクターを使用しても (適切に設計されている限り)、ほとんどわかりません。

たとえば、Move コンストラクターと Move 代入演算子を追加すると、実際に効果が現れるのはいつですか?

したがって、移動のセマンティクスを調べたい場合は、移動コンストラクターを使用してサンプル コードを作成することをお勧めします。

于 2011-07-28T20:26:14.533 に答える
0

std::move の詳しい説明については、こちらを参照してください。move コンストラクターの使用を開始しない限り、この新しい機能を効果的に使用することはできません。また、コピーにオーバーヘッドがないプリミティブ型には意味がないと思います。

于 2011-07-28T21:32:26.993 に答える
0
//val is  destroy here ?

パラメータの型が であった場合と同じ答えconst int& val

//undefined behavior if I reference here nb ?

いいえ。ただし、出力される値は指定されていません。これは、何かが起こる可能性があることを意味する「未定義の動作」とは異なります。未定義の動作である場合、ディスクが再フォーマットされる可能性があることを意味します。

于 2011-07-28T20:14:29.303 に答える