Referencias Rvalue y Lvalue
Desliza para mostrar el menú
Los conceptos de lvalue y rvalue se utilizan para clasificar las expresiones en dos tipos: aquellas que tienen una ubicación estable en memoria y aquellas que son temporales.
Un lvalue (valor izquierdo) es una expresión que se refiere a una ubicación específica en la memoria. En términos simples, es una variable con un nombre que se puede modificar.
int x = 10;
Aquí, x es un lvalue porque tiene un nombre, existe en memoria y su valor puede cambiarse (x = 20).
Un rvalue (valor derecho) es un valor temporal que no tiene su propio nombre y solo existe durante la evaluación de una expresión.
10
x + 5
int y = x + 5;
Aquí, x + 5 es un rvalue porque es solo el resultado de un cálculo, no se almacena como un objeto separado y no puede modificarse directamente.
Idea simple:
- lvalue: algo con un nombre y una dirección de memoria (una variable);
- rvalue: un resultado temporal (un valor o expresión).
Valores temporales
Un valor temporal es un resultado intermedio y de corta duración creado durante la evaluación de una expresión.
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);
Los valores temporales son gestionados automáticamente por el compilador y existen durante la expresión u operación en la que se crean. Después de eso, normalmente se descartan y el resultado se almacena en la variable de destino o se utiliza según sea necesario.
Semántica de movimiento
Una referencia a rvalue se denota mediante el doble ampersand (&&).
La única diferencia entre una referencia a lvalue y una referencia a rvalue es que la rvalue puede vincularse a un objeto temporal, mientras que una referencia a lvalue no puede.
int&& ref_value = 5 * 5;
El uso de una referencia a rvalue en este contexto puede no ser muy práctico, ya que no hay beneficio en utilizar una referencia a rvalue para un literal simple.
Una combinación de referencias lvalue y referencias rvalue se utiliza para soportar la semántica de movimiento, permitiendo que los recursos se transfieran de un objeto a otro sin copias innecesarias. Observe el siguiente ejemplo:
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` }
Pero no necesitamos copias de a o b. Simplemente queríamos intercambiarlos. Intentémoslo de nuevo.
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 un lvalue en una referencia rvalue, permitiendo la semántica de movimiento y la transferencia de propiedad sin copiar.
¡Gracias por tus comentarios!
Pregunte a AI
Pregunte a AI
Pregunte lo que quiera o pruebe una de las preguntas sugeridas para comenzar nuestra charla