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