Referências Rvalue e Lvalue
Deslize para mostrar o menu
Os conceitos de lvalue e rvalue são utilizados para classificar expressões em dois tipos: aquelas que possuem um local estável na memória e aquelas que são temporárias.
Um lvalue (left value) é uma expressão que se refere a um local específico na memória. Em termos simples, é uma variável com um nome que pode ser modificada.
int x = 10;
Aqui, x é um lvalue porque possui um nome, existe na memória e seu valor pode ser alterado (x = 20).
Um rvalue (right value) é um valor temporário que não possui um nome próprio e existe apenas durante a avaliação de uma expressão.
10
x + 5
int y = x + 5;
Aqui, x + 5 é um rvalue porque é apenas o resultado de um cálculo, não é armazenado como um objeto separado e não pode ser modificado diretamente.
Ideia simples:
- lvalue: algo com um nome e um endereço de memória (uma variável);
- rvalue: um resultado temporário (um valor ou expressão).
Valores Temporários
Um valor temporário é um resultado intermediário de curta duração criado durante a avaliação de uma expressão.
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);
Valores temporários são gerenciados automaticamente pelo compilador e existem durante a expressão ou operação em que são criados. Após isso, normalmente são descartados, e o resultado é armazenado na variável de destino ou utilizado conforme necessário.
Semântica de movimento
Uma referência a rvalue é denotada por dois e comerciais (&&).
A única diferença entre uma referência a lvalue e uma referência a rvalue é que a rvalue pode ser vinculada a um objeto temporário, enquanto uma referência a lvalue não pode.
int&& ref_value = 5 * 5;
Utilizar uma referência a rvalue neste contexto pode não ser muito prático, pois não há benefício em usar uma referência a rvalue para um literal simples
Uma combinação de referências lvalue e rvalue é utilizada para suportar semântica de movimento, permitindo que recursos sejam transferidos de um objeto para outro sem cópias desnecessárias. Veja o exemplo abaixo:
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` }
Mas não precisamos de cópias de a ou b. Queríamos apenas trocá-los. Vamos tentar novamente.
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(): transforma um lvalue em uma referência rvalue, habilitando semântica de movimento e a transferência de propriedade sem cópia.
Obrigado pelo seu feedback!
Pergunte à IA
Pergunte à IA
Pergunte o que quiser ou experimente uma das perguntas sugeridas para iniciar nosso bate-papo