Lvalues 和 Rvalues (C++)

每個 C++ 運算式都有一個型別,且屬於 值類別目錄。 值類別是編譯程式在表達式評估期間建立、複製和移動暫存物件時必須遵循的規則基礎。

C++17 標準會定義表達式值類別,如下所示:

  • glvalue 是表示式,其評估會決定物件、位字段或函式的識別。
  • prvalue 是表示式,其評估會初始化物件或位字段,或計算運算子的操作數值,如其出現的內容所指定。
  • xvalue 是表示物件或位字段的 glvalue,其資源可以重複使用(通常是因為它接近其存留期的結尾)。 範例:某些涉及右值參考 (8.3.2) 的運算式會產生 xvalue,例如呼叫傳回型別為右值參考的函式,或轉換成右值參考型別。
  • 左值是不是 xvalue 的 glvalue。
  • 右值是 prvalue 或 xvalue。

下圖說明類別之間的關聯性:

Diagram of C++ expression value categories.

此圖表的開頭為方塊捲標表達式,其中包含兩個子系:glvalue 和 rvalue。 glvalue 有兩個子系:lvalue 和 xvalue。 rvalue 有兩個子系:prvalue 和 xvalue;xvalue 也是 glvalue 的子系。

左值具有程式可存取的位址。 左值表達式的範例包括變數名稱,包括 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
}

注意

本主題中的範例將說明運算子未多載時的正確和不正確用法。 藉由多載運算子,您就可以讓像是 j * 4 這樣的運算式變成左值。

當您參考對象參考時,通常會使用左值和右值詞彙。 如需參考的詳細資訊,請參閱 左值參考宣告子:&Rvalue 參考宣告子: &&&

另請參閱

基本概念
左值參考宣告子:&
右值參考宣告子:&&