Riferimenti Rvalue e Lvalue
Scorri per mostrare il menu
I concetti di lvalue e rvalue vengono utilizzati per classificare le espressioni in due tipi: quelle che hanno una posizione stabile in memoria e quelle che sono temporanee.
Un lvalue (left value) è un'espressione che si riferisce a una posizione specifica in memoria. In termini semplici, è una variabile con un nome che può essere modificata.
int x = 10;
Qui, x è un lvalue perché ha un nome, esiste in memoria e il suo valore può essere cambiato (x = 20).
Un rvalue (right value) è un valore temporaneo che non ha un proprio nome ed esiste solo durante la valutazione di un'espressione.
10
x + 5
int y = x + 5;
Qui, x + 5 è un rvalue perché è solo il risultato di un calcolo, non viene memorizzato come oggetto separato e non può essere modificato direttamente.
Idea semplice:
- lvalue: qualcosa con un nome e un indirizzo di memoria (una variabile);
- rvalue: un risultato temporaneo (un valore o un'espressione).
Valori Temporanei
Un valore temporaneo è un risultato intermedio e di breve durata creato durante la valutazione di un'espressione.
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);
I valori temporanei sono gestiti automaticamente dal compilatore ed esistono per la durata dell'espressione o dell'operazione in cui vengono creati. Successivamente, vengono generalmente eliminati e il risultato viene memorizzato nella variabile di destinazione o utilizzato secondo necessità.
Semantica di spostamento
Un riferimento rvalue è indicato dal doppio e commerciale (&&).
L'unica differenza tra un riferimento lvalue e rvalue è che il rvalue può essere associato a un oggetto temporaneo, mentre un riferimento lvalue non può.
int&& ref_value = 5 * 5;
L'utilizzo di un riferimento rvalue in questo contesto potrebbe non essere molto pratico, poiché non vi è alcun vantaggio nell'usare un riferimento rvalue per un semplice valore letterale.
Una combinazione di riferimenti lvalue e rvalue viene utilizzata per supportare la move semantics, consentendo il trasferimento delle risorse da un oggetto a un altro senza copie non necessarie. Osserva l'esempio qui sotto:
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` }
Ma non abbiamo bisogno di copie di a o b. Vogliamo semplicemente scambiarli. Proviamo di nuovo.
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(): trasforma un lvalue in un riferimento rvalue, abilitando le move semantics e il trasferimento della proprietà senza copia.
Grazie per i tuoi commenti!
Chieda ad AI
Chieda ad AI
Chieda pure quello che desidera o provi una delle domande suggerite per iniziare la nostra conversazione