通常、何かが左辺値か右辺値かを知る必要があるだけです。これら 2 つの式のカテゴリは、互いに区別されます。
通常、左辺値式は、しばらくぶらぶらする何かを参照する場合です。たとえば、変数は固定されているため、変数名は左辺値です。一方、右辺値式は通常、一時的にしか存在しないものを参照します。左辺値のアドレスしか取得できません。なぜなら、すぐに消えてしまうもののアドレスが必要になるからです。
さて、この区別をするときは、コンパイラがその時点で知っていることを考慮に入れる必要があります。たとえば、関数を取り上げますvoid foo(const A& a)
。この関数内では、コンパイラは渡されたオブジェクトが一時オブジェクトであるかどうかを認識していないため、そのまま残ると想定しています。つまりa
、左辺値です。一時オブジェクトをこの関数に渡す (右辺値式で呼び出す) ことはできますが、式a
は依然として左辺値です。
これを考慮に入れると、名前が付けられているかどうかによって、何かが左辺値か右辺値かをさらに思い出すことができます。上記の例では、オブジェクトは として名前が付けられるためa
、左辺値です。
さて、残りのカテゴリについては、次の図を覚えておく必要があります。
左辺値と右辺値は実際には異なることに注意してください。ただし、右辺値は、xvalues と prvalues という 2 つの別のカテゴリに分割されます。また、xvalue もすべての lvalue 式と共に glvalue と見なされます。
これらがいつ現れるかを知ることは、いくつかのケースを思い出すことに帰着します。
xvaluesはあまり一般的ではありません。これらは、右辺値参照への変換を伴う状況でのみ表示されます。すべてのケースは次のとおりです。
- 右辺値参照を返す関数の結果
- 右辺値参照へのキャスト
object.x
object
xvalue の場合
object.*member
pobject
xvalue の場合
定義上、prvaluesは、xvalue ではない他のすべてのタイプの右辺値です。たとえば、関数から値によってオブジェクトを返すと、一時的に返されるオブジェクトが作成されます。オブジェクトが prvalue であることを示す式。
カテゴリglvalueは、prvalue ではないすべてのものを参照するために使用されます。