In C++, an lvalue (short for "locator value") is an expression that refers to a memory location. Lvalues have a persistent storage location, meaning you can take their address using the & operator, and they can appear on the left-hand side of an assignment operation. In contrast, an rvalue (right value) is a temporary value that does not have a persistent memory location.
Understanding lvalues is crucial for grasping C++'s assignment rules, reference types, and move semantics. Here's a deeper dive into lvalues and how they differ from rvalues.
& operator.#include <iostream>
int main() {
int x = 10; // 'x' is an lvalue
int* ptr = &x; // You can take the address of 'x'
std::cout << "x: " << x << std::endl;
std::cout << "Address of x: " << ptr << std::endl;
*ptr = 20; // You can modify the value of 'x' through 'ptr'
std::cout << "Modified x: " << x << std::endl;
return 0;
}
x: This is an lvalue because it refers to a specific memory location that stores the value 10.&x: The address-of operator can be used on x, confirming that x is an lvalue.x can be modified through a pointer.#include <iostream>
int main() {
int a = 5;
int b = 10;
a = b; // 'a' and 'b' are both lvalues
b = 20; // You can assign to an lvalue
std::cout << "a: " << a << std::endl;
std::cout << "b: " << b << std::endl;
return 0;
}
a and b are lvalues because they represent variables that refer to specific memory locations. The expression a = b assigns the value of b to a.a = b, a is on the left-hand side, demonstrating that lvalues can be assigned to.Lvalue references (denoted by T&) are a way to refer to an existing lvalue. Lvalue references are used to create aliases for lvalues and can be used to pass large objects efficiently to functions.
#include <iostream>
void modify(int& ref) {
ref += 10; // Modify the lvalue reference
}
int main() {
int value = 30;
modify(value); // Pass 'value' as an lvalue reference
std::cout << "Modified value: " << value << std::endl;
return 0;
}
int& ref is an lvalue reference, meaning it must be initialized with an lvalue. In this case, value is passed as an lvalue to the modify function.ref.const, meaning they cannot be modified. A const lvalue reference can bind to both lvalues and rvalues.#include <iostream>
void print(const int& ref) {
std::cout << "Value: " << ref << std::endl;
}
int main() {
int a = 50;
const int& refA = a; // 'refA' is a const lvalue reference
print(a); // Pass lvalue
print(100); // Pass rvalue, still works with const reference
return 0;
}
const int& refA = a;: This is a const lvalue reference, which can refer to both lvalues (like a) and rvalues (like 100).const lvalue reference, allowing it to be called with both lvalues and rvalues.#include <iostream>
int main() {
int x = 10; // 'x' is an lvalue
int y = x + 5; // 'x + 5' is an rvalue
int* p1 = &x; // OK: 'x' is an lvalue
// int* p2 = &(x + 5); // Error: 'x + 5' is an rvalue, can't take its address
y = 15; // OK: 'y' is an lvalue
return 0;
}
x is an lvalue, representing a variable with a memory location. You can take its address and modify it.x + 5 is an rvalue, a temporary value. You cannot take the address of an rvalue.Understanding lvalues is fundamental to mastering references, assignment operations, and more advanced topics like move semantics and perfect forwarding in C++.
Previous Page | Course Schedule | Course Content