Try   HackMD

C++ 左值與右值

在 C++ 的任何運算式當中,都有包含所謂左值(lvalue)以及右值(rvalue),在解釋之前先看以下程式碼:

int x = 42069;

在這個範例中42069 是右值(專業術語是 literal constant)、變數 x 是左值,最直接的差別就是,右值我們沒有明確的定義其記憶體位置,而左邊的變數 x 是有記憶體位址的。

int* p = &x;

而在這邊的程式碼中,& 是一個取址運算元,它接收一個變數(左值)即可產生其變數的記憶體位址(右值),並最後 assgin 給指標 p,所以它也是一個左值,因為它也有自己的記憶體位置。

你不可能這樣寫:

int x; 666 = x; //error: lvalue required as left operand of assignment int* p = &666; //error: lvalue required as unary '&' operand

左右值參考

// 左值參考 int a = 5; int& b = a; // 右值參考 int& c = 5; // error: cannot bind non-const lvaule refernce of type 'int&' to an rvalue of type 'int' const int& d = 5; // OK int&& e = 5; // OK

參考只能參考左值,這其實很合理因為右值本身就是暫時的值,它隨時都可能被釋放,而且也沒有具體的記憶體位址,你參考右值是很奇怪的。但是如果你多加個 const 的話,就可以參考右值了,看以下範例:

void magic(int& x, int& y) {
    x = x + 2;
    y = x + y;
}

int main() {
    int a = 2;
    int b = 3;
    magic(a, b);
    
    // 錯誤:非常數參考的初始值必須是左值
    // magic(5, 8);
    return 0;
}

參考只能接受左值,如果要接收右值,就必須是 const 才能去參考右值,為甚麼呢?可以這樣思考:右值是程式臨時產生出來的值,不可以被修改,所以說必須加上修飾詞 const 才可以去參考右值。

結論

  • 左值:任何有記憶體位址的變數都是左值,包括不可修改的 const 變數。
  • 右值:非左值即右值,通常也是運算式所產生暫時的值。
tags: C++