Rvalue and Lvalue References
Deslize para mostrar o menu
The concepts of lvalue and rvalue are used to classify expressions into two types: those that have a stable location in memory and those that are temporary.
An lvalue (left value) is an expression that refers to a specific location in memory. In simple terms, it’s a variable with a name that you can modify.
int x = 10;
Here, x is an lvalue because it has a name, exists in memory, and its value can be changed (x = 20).
An rvalue (right value) is a temporary value that does not have its own name and only exists during the evaluation of an expression.
10
x + 5
int y = x + 5;
Here, x + 5 is an rvalue because it’s just the result of a computation, not stored as a separate object, and cannot be modified directly.
Simple idea:
- lvalue: something with a name and a memory address (a variable);
- rvalue: a temporary result (a value or expression).
Temporary Values
A temporary value is a short-lived, intermediate result created during the evaluation of an expression.
rvalue.h
12345678// `(27 + 6 + 3 + 2)` is a tempopary value int sum = 27 + 6 + 3 + 2; // `static_cast<float>(sum)` is a tempopary value float avarage = static_cast<float>(sum) / count; // std::max(7, 9) will return a tempopary value int largest = std::max(7, 9);
Temporary values are automatically managed by the compiler, and they exist for the duration of the expression or operation where they are created. After that, they are typically discarded, and the result is stored in the target variable or used as needed.
Move semantics
An rvalue reference is denoted by the double ampersand (&&).
The only difference between an lvalue and rvalue reference is that rvalue can be bound to a temporary object, whereas an lvalue reference cannot.
int&& ref_value = 5 * 5;
Using an rvalue reference in this context might not be very practical, as there is no benefit to using an rvalue reference for a simple literal
A combination of lvalue and rvalue references is used to support move semantics, allowing resources to be transferred from one object to another without unnecessary copying. Look at the example below:
swap.h
123456std::string swap(std::string& a, std::string& b) { std::string tmp(a); // We have two copies of string `a` a = b; // Now we have two copies of string `b` b = tmp; // And now we have two copies of string `tmp` }
But we don't need copies of a or b. We simply wanted to swap them. Let's try again.
main.cpp
1234567891011121314151617181920212223#include <iostream> void swap(std::string &a, std::string &b) { // Move the content of a into temp std::string temp(std::move(a)); // Move the content of b into a a = std::move(b); // Move the content of temp into b b = std::move(temp); } int main() { std::string a = "Hello\n"; std::string b = "Bye\n"; swap(a, b); std::cout << a << b; }
std::move(): transforms an lvalue into an rvalue reference, enabling move semantics and the transfer or ownership without copying.
Obrigado pelo seu feedback!
Pergunte à IA
Pergunte à IA
Pergunte o que quiser ou experimente uma das perguntas sugeridas para iniciar nosso bate-papo