左辺値と右辺値 (C++)

すべての C++ 式は 型を持ち、値カテゴリに属します。 値カテゴリは、式の評価中に一時オブジェクトを作成、コピー、および移動するときにコンパイラが従う必要があるルールの基礎です。

C++17 標準では、式の値のカテゴリを次のように定義します。

  • glvalue は、評価によってオブジェクト、ビット フィールド、または関数の ID を決定する式です。
  • prvalue は、評価でオブジェクトまたはビット フィールドを初期化する式です。または、表示されるコンテキストで指定された演算子のオペランドの値を計算する式です。
  • xvalue は、リソースを再利用できるオブジェクトまたはビット フィールドを表す glvalue です (通常は、有効期間の終わり近くにあるため)。 例: rvalue 参照 (8.3.2) を含む特定の種類の式では、戻り値の型が右辺値参照である関数の呼び出しや、右辺値参照型へのキャストなど、xvalue が生成されます。
  • 左辺値は、xvalue ではない glvalue です。
  • rvalue は prvalue または xvalue です。

次の図は、カテゴリ間の関係を示しています。

Diagram of C++ expression value categories.

図は、glvalue と右辺値の 2 つの子を持つ、式というラベルが付いたボックスで始まります。 glvalue には、左辺値と xvalue の 2 つの子があります。 rvalue には、prvalue と xvalue の 2 つの子があります。xvalue は glvalue の子でもあります。

lvalue には、プログラムがアクセスできるアドレスがあります。 左辺値式の例としては、const 変数、配列要素、左辺値参照を返す関数呼び出し、ビット フィールド、共用体、クラス メンバーなどの変数名があります。

prvalue 式には、プログラムからアクセスできるアドレスはありません。 prvalue 式の例としては、リテラル、非参照型を返す関数呼び出し、式の評価時に作成されるがコンパイラのみがアクセスできる一時オブジェクトなどがあります。

xvalue 式には、プログラムからアクセスできなくなったが、式へのアクセスを提供する右辺値参照を初期化するために使用できるアドレスがあります。 たとえば、右辺値参照を返す関数呼び出しや、配列またはオブジェクトが右辺値参照であるメンバー式への配列添字、メンバー、ポインターなどです。

次の例は、左辺値と右辺値の正しい使用方法と間違った使用方法のいくつかを示しています。

// lvalues_and_rvalues2.cpp
int main()
{
    int i, j, *p;

    // Correct usage: the variable i is an lvalue and the literal 7 is a prvalue.
    i = 7;

    // Incorrect usage: The left operand must be an lvalue (C2106).`j * 4` is a prvalue.
    7 = i; // C2106
    j * 4 = 7; // C2106

    // Correct usage: the dereferenced pointer is an lvalue.
    *p = i;

    // Correct usage: the conditional operator returns an lvalue.
    ((i < 3) ? i : j) = 7;

    // Incorrect usage: the constant ci is a non-modifiable lvalue (C3892).
    const int ci = 7;
    ci = 9; // C3892
}

Note

このトピックの例では、演算子がオーバーロードしていないときの、正しい方法使用と正しくない使用方法を説明します。 演算子をオーバーロードすることにより、j * 4 のような式を左辺値にできます。

左辺値右辺値という用語は、オブジェクト参照を参照するときによく使われます。 参照の詳細については、「左辺値参照宣言子: > および右辺値参照宣言子: &>」を参照してください。

関連項目

基本的な概念
左辺値参照宣言子: &
右辺値参照宣言子: &&