Lvalues dan Rvalues (C++)

Setiap ekspresi C++ memiliki jenis, dan termasuk dalam kategori nilai. Kategori nilai adalah dasar untuk aturan yang harus diikuti pengkompilasi saat membuat, menyalin, dan memindahkan objek sementara selama evaluasi ekspresi.

Standar C++17 mendefinisikan kategori nilai ekspresi sebagai berikut:

  • Glvalue adalah ekspresi yang evaluasinya menentukan identitas objek, bit-field, atau fungsi.
  • Prvalue adalah ekspresi yang evaluasinya menginisialisasi objek atau bit-field, atau menghitung nilai operand operator, seperti yang ditentukan oleh konteks munculnya.
  • Xvalue adalah glvalue yang menunjukkan objek atau bit-field yang sumber dayanya dapat digunakan kembali (biasanya karena mendekati akhir masa pakainya). Contoh: Jenis ekspresi tertentu yang melibatkan referensi rvalue (8.3.2) menghasilkan xvalue, seperti panggilan ke fungsi yang jenis pengembaliannya adalah referensi rvalue atau cast ke jenis referensi rvalue.
  • Lvalue adalah glvalue yang bukan xvalue.
  • Rvalue adalah prvalue atau xvalue.

Diagram berikut mengilustrasikan hubungan antara kategori:

Diagram of C++ expression value categories.

Diagram dimulai dengan ekspresi berlabel kotak, yang memiliki dua anak: glvalue dan rvalue. glvalue memiliki dua anak: lvalue dan xvalue. rvalue memiliki dua anak: prvalue dan xvalue; xvalue juga merupakan anak dari glvalue.

Lvalue memiliki alamat yang dapat diakses program Anda. Contoh ekspresi lvalue termasuk nama variabel, termasuk const variabel, elemen array, panggilan fungsi yang mengembalikan referensi lvalue, bit-field, union, dan anggota kelas.

Ekspresi prvalue tidak memiliki alamat yang dapat diakses oleh program Anda. Contoh ekspresi prvalue termasuk literal, panggilan fungsi yang mengembalikan jenis nonreferensi, dan objek sementara yang dibuat selama evaluasi ekspresi tetapi hanya dapat diakses oleh pengkompilasi.

Ekspresi xvalue memiliki alamat yang tidak lagi dapat diakses oleh program Anda tetapi dapat digunakan untuk menginisialisasi referensi rvalue, yang menyediakan akses ke ekspresi. Contohnya termasuk panggilan fungsi yang mengembalikan referensi rvalue, dan subskrip array, anggota, dan penunjuk ke ekspresi anggota di mana array atau objek adalah referensi rvalue.

Contoh

Contoh berikut menunjukkan beberapa penggunaan lvalue dan rvalue yang benar dan salah:

// 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
}

Catatan

Contoh dalam topik ini menggambarkan penggunaan yang benar dan salah ketika operator tidak kelebihan beban. Dengan kelebihan beban operator, Anda dapat membuat ekspresi seperti j * 4 lvalue.

Istilah lvalue dan rvalue sering digunakan saat Anda merujuk ke referensi objek. Untuk informasi selengkapnya tentang referensi, lihat Deklarator Referensi Lvalue: & dan Deklarator Referensi Rvalue: &&&.

Baca juga

Konsep Dasar
Deklarator Referensi Lvalue: &
Deklarator Referensi Rvalue: && &