Co je lvalue a rvalue v C++?
V programovacím jazyce C++ se často setkáváme s pojmy jako lvalue a rvalue. Tyto termíny jsou klíčové pro pochopení toho, jak C++ pracuje s hodnotami a proměnnými. V tomto článku si vysvětlíme, co tyto pojmy znamenají, jaký je mezi nimi rozdíl a proč jsou důležité.
Co je lvalue?
Lvalue (z anglického „left value“) označuje výraz, který odkazuje na konkrétní paměťové místo. Jinými slovy, lvalue je něco, co má adresu a může být na levé straně přiřazovacího výrazu. Typickým příkladem lvalue je proměnná.
Příklad lvalue:
int x = 10; // x je lvalue
x = 20; // x je na levé straně přiřazení
V tomto příkladu je x lvalue, protože odkazuje na konkrétní paměťové místo, kam lze uložit hodnotu.
Lvalue může být také složitější výraz, pokud stále odkazuje na konkrétní paměťové místo:
int arr[3] = {1, 2, 3};
arr[0] = 5; // arr[0] je lvalue
Co je rvalue?
Rvalue (z anglického „right value“) označuje výraz, který neodkazuje na konkrétní paměťové místo. Rvalue je dočasná hodnota, která existuje pouze během vyhodnocení výrazu. Typickým příkladem rvalue jsou literály nebo výsledky výpočtů.
Příklad rvalue:
int y = 10; // 10 je rvalue
int z = y + 5; // (y + 5) je rvalue
V tomto příkladu je hodnota 10 rvalue, protože je to literál, který nemá konkrétní adresu v paměti. Podobně výraz y + 5 je rvalue, protože jde o dočasnou hodnotu.
Rvalue nemůže být na levé straně přiřazovacího výrazu:
10 = x; // Chyba! 10 je rvalue a nelze jí přiřadit hodnotu
Lvalue a rvalue reference
Od C++11 byly zavedeny tzv. rvalue reference, které umožňují efektivnější práci s dočasnými hodnotami. Rvalue reference se deklarují pomocí && a umožňují například přesun dat místo jejich kopírování (move semantics).
Příklad rvalue reference:
int&& rref = 10; // rref je rvalue reference
Rvalue reference se často používají v kombinaci s funkcemi, které implementují přesun dat:
#include <iostream>
#include <string>
void printAndClear(std::string&& str) {
std::cout << str << std::endl;
str.clear();
}
int main() {
std::string temp = "Hello, World!";
printAndClear(std::move(temp)); // std::move vytvoří rvalue z lvalue
return 0;
}
Shrnutí
- Lvalue: Odkazuje na konkrétní paměťové místo, může být na levé straně přiřazení.
- Rvalue: Dočasná hodnota, která nemá konkrétní adresu, nemůže být na levé straně přiřazení.
- Rvalue reference: Zavedeny v C++11, umožňují efektivní práci s dočasnými hodnotami.
Pochopení rozdílu mezi lvalue a rvalue je klíčové pro psaní efektivního a moderního C++ kódu. Tyto koncepty jsou základem pro pokročilé techniky, jako je přesunová semantika, optimalizace výkonu a práce s pamětí.