C++左の値と右の値と移動の意味


最近多くの関連ブログを見て、自分で総括して、単純に等号の左か右かで明らかに判断するのがあまりにも粗雑で、私の大まかな理解は以下の通りです:objectが左か右かを判断します:(1)objectが住所を取られるかどうか、すなわち&objectが合っているかどうか;(2)objectが付与されるかどうか、すなわちobject=other_objectが合法かどうか;(3)objectは、現在の文の実行が完了しても破棄されますか、すなわち、一時オブジェクトか永続オブジェクトか.次に、左値参照と右値参照ですが、両者は参照を指します.左値参照は左値、右値参照は右値です.さらに説明するために、次の例を見てみましょう.
int add(int a, int b)
{
    return a + b;
}
cout << add(2, 3);

これは最も簡単なバージョンで、参照は使用されていませんが、関数呼び出しと戻り中に複数回のコピーが消費され、計算リソースが浪費されます.次に、左の参照を見てみましょう.
int& add(int a, int b)
{
    return a + b;
}
cout << add(2, 3);

ここで期待される戻り値は左値参照であるが、関数内で返されるのは(a+b)であり、開始の判断方法によっては右値であり、左値参照に値を付与することはできない(vs 2013「非常量参照の初期値は左値でなければならない」と提示されている).非常量参照を強調する以上、私はまた(a+b)を1つの変数に値を割り当ててからその変数を返したくありません(面倒です)、それでは定数の左の値の参照を返すことを期待するように修正しましょう.以下のように修正します.
const int & add(int a, int b)
{
    return a + b;
}
cout << add(2, 3);

では、また変更しますか.次のようになります.
const int & add(int& a, int& b)
{
    return a + b;
}
cout << add(2, 3);

このように関数の定義は間違いありませんが、呼び出しに問題が発生します.期待される受信パラメータは左値参照ですが、私は2と3のような右値を入力します.ここでは、(1)パラメータを常左値参照に変更する2つの方法があります.
const int & add(const int& a,const int& b)
{
    return a + b;
}
cout << add(2, 3);

(2)右値の実パラメータを左値に変換して関数を転送する.
int x=2,y=3;
const int & add( int& a, int& b)
{
    return a + b;
}
cout << add(x, y);

次に、右の参照バージョンを見てみましょう.
int && add(int a, int b)
{
    return a + b;
}
cout << add(x, y);

これは問題ありませんが、次の場合に変更します.
int && add(int a, int b)
{
    int sum= a + b;
    return sum;
}
cout << add(x, y);

VS 2013ヒント右参照を左にバインドできない場合は、左を右に変換します.
int && add(int a, int b)
{
    int sum= a + b;
    return std::move(sum);
}
cout << add(x, y);

ここまで、例はもういいです.まとめてみると、(1)値の伝達にはあまり考慮されていません.効率が低く、コンパイルの正確性に影響しません.(2)右値参照は右値にのみバインドできます.(3)左値参照は左値にのみバインドできます.(4)常左値参照は右値にバインドできます.(5)右の値が1つの変数に与えられた後、左の値として表すことができる.(6)std::move()を使用して左値を右値に変換します.はい、以上の知識を使うと、左右の値の引用によるコンパイルエラーを避けることができます.これは私の理解です.