C++左と右
1699 ワード
左、右
C++11のすべての値は必ず左、右のいずれかに属し、右の値は純右に細分化され、亡き値になります.C++11でアドレスを取ることができるのは、名前があるのが左で、逆に、アドレスを取ることができないのは、名前がないのが右(将亡値または純右値)です.例えば、int a=b+c、aは左の値であり、変数名はaであり、&aによってその変数のアドレスを取得することができる.式b+c、関数int func()の戻り値は右値であり、ある変数に値を割り当てる前に変数名で見つけることはできません.&(b+c)のような操作はコンパイルされません.
右の値、死亡する値
C++11の右の値を理解する前に、C++98の右の値の概念を見てみましょう.C++98の右の値は純右の値で、純右の値は一時変数の値で、対象と関連しない字面量の値を指します.一時変数とは、非参照で返される関数の戻り値、式などを指し、例えば関数int func()の戻り値、式a+b;オブジェクトに関連付けられていない字面量の値、例えばtrue,2,“C”など.C++11は、C++98の右の値を拡張する.C++11では右の値は純右の値(prvalue,Pure Rvalue)と将亡の値(xvalue,eXpiring Value)に分けられます.ここで、純右値の概念は、C++98規格における右値の概念と同等であり、一時変数とオブジェクトに関連付けられていない字面量値を指す.亡き値は、C++11に追加された右値参照に関連する式であり、通常は、右値参照T&&を返す関数の戻り値、std::moveの戻り値、またはT&&に変換するタイプの変換関数の戻り値など、移動するオブジェクト(他に移動)を返します.亡き値は、他の変数のメモリ領域を「盗む」ことによって取得された値として理解できます.他の変数が使用されなくなったり、破棄されそうになったりした場合、「盗む」ことでメモリ領域の解放と割り当てを回避し、変数値のライフサイクルを延長できます.
左参照、右参照
左参照とは、左の値を参照するタイプです.右の値の参照は、右の値を参照するタイプです.実際には、右の値には通常名前がないため、参照によってしか存在しません.右参照と左参照は、いずれも参照タイプに属します.左参照を宣言しても右参照を宣言しても、すぐに初期化する必要があります.その理由は、参照タイプ自体がバインドされたオブジェクトのメモリを持っておらず、そのオブジェクトの別名であると理解できます.左参照は変数値を持つ別名であり、右参照は変数を持たない別名です.左参照は通常、右にバインドすることはできませんが、定数の左参照は万能の参照タイプです.非常量の左、定数の左、右の値を初期化できます.ただし、定数の左の値が参照する右の値は、その「余生」では読み取り専用になります.対照的に、非常量左値は、非常量左値の初期化しか受け入れられない.
右値参照は通常、任意の左値にバインドできません.左値から右値参照をバインドするには、std::move()左値を強制的に右値に変換する必要があります.たとえば、次のようにします.
C++11のすべての値は必ず左、右のいずれかに属し、右の値は純右に細分化され、亡き値になります.C++11でアドレスを取ることができるのは、名前があるのが左で、逆に、アドレスを取ることができないのは、名前がないのが右(将亡値または純右値)です.例えば、int a=b+c、aは左の値であり、変数名はaであり、&aによってその変数のアドレスを取得することができる.式b+c、関数int func()の戻り値は右値であり、ある変数に値を割り当てる前に変数名で見つけることはできません.&(b+c)のような操作はコンパイルされません.
右の値、死亡する値
C++11の右の値を理解する前に、C++98の右の値の概念を見てみましょう.C++98の右の値は純右の値で、純右の値は一時変数の値で、対象と関連しない字面量の値を指します.一時変数とは、非参照で返される関数の戻り値、式などを指し、例えば関数int func()の戻り値、式a+b;オブジェクトに関連付けられていない字面量の値、例えばtrue,2,“C”など.C++11は、C++98の右の値を拡張する.C++11では右の値は純右の値(prvalue,Pure Rvalue)と将亡の値(xvalue,eXpiring Value)に分けられます.ここで、純右値の概念は、C++98規格における右値の概念と同等であり、一時変数とオブジェクトに関連付けられていない字面量値を指す.亡き値は、C++11に追加された右値参照に関連する式であり、通常は、右値参照T&&を返す関数の戻り値、std::moveの戻り値、またはT&&に変換するタイプの変換関数の戻り値など、移動するオブジェクト(他に移動)を返します.亡き値は、他の変数のメモリ領域を「盗む」ことによって取得された値として理解できます.他の変数が使用されなくなったり、破棄されそうになったりした場合、「盗む」ことでメモリ領域の解放と割り当てを回避し、変数値のライフサイクルを延長できます.
左参照、右参照
左参照とは、左の値を参照するタイプです.右の値の参照は、右の値を参照するタイプです.実際には、右の値には通常名前がないため、参照によってしか存在しません.右参照と左参照は、いずれも参照タイプに属します.左参照を宣言しても右参照を宣言しても、すぐに初期化する必要があります.その理由は、参照タイプ自体がバインドされたオブジェクトのメモリを持っておらず、そのオブジェクトの別名であると理解できます.左参照は変数値を持つ別名であり、右参照は変数を持たない別名です.左参照は通常、右にバインドすることはできませんが、定数の左参照は万能の参照タイプです.非常量の左、定数の左、右の値を初期化できます.ただし、定数の左の値が参照する右の値は、その「余生」では読み取り専用になります.対照的に、非常量左値は、非常量左値の初期化しか受け入れられない.
int &a = 2; # ,
int b = 2; #
const int &c = b; # ,
const int d = 2; #
const int &e = c; # ,
const int &b =2; # ,
右値参照は通常、任意の左値にバインドできません.左値から右値参照をバインドするには、std::move()左値を強制的に右値に変換する必要があります.たとえば、次のようにします.
int a;
int &&r1 = c; #
int &&r2 = std::move(a); #