Кратко
- Lvalue - выражения, которые имеют адрес в памяти. Могут стоять слева и справа от оператора присваивания.
- Rvalue (
&&
) - временные выражения, которые не имеют адреса в памяти. Могут стоять только справа от оператора присваивания.
пример:
int a = 5; // a - lvalue, 5 - rvalue
int b = a; // a - lvalue, b - lvalue, a (справа) - lvalue, ведет себя как rvalue
b = 10; // b - lvalue, 10 - rvalue
Классификация значений по идентифицируемости и перемещаемости
-
По идентифицируемости значения разделяются на rvalue и lvalue
-
По перемещаемости:
-
Копируемые объекты - объекты, которые могут быть скопированы в другой объект без изменения оригинала.
-
Перемещаемые объекты - объекты, которые могут быть перемещены в другой объект без копирования данных.
-
Rvalue-ссылки (C++11 и выше)
- Rvalue-ссылки: позволяют привязывать временные объекты к ссылкам, что позволяет реализовать семантику перемещения и избежать ненужных копирований.
#include <iostream>
// Функция принимает rvalue-ссылку на строку и выводит её содержимое
void printString(std::string&& str) {
std::cout << "Received string: " << str << std::endl;
// Допустим, здесь могут быть другие операции с переданной строкой
}
int main() {
// Создаём временный объект типа std::string
std::string temp = "Hello, World!";
// Передаём временный объект в функцию через std::move
printString(std::move(temp));
// В этой точке temp больше не используется, она пустая
return 0;
}
Преимущества использования rvalue-ссылок
- Семантика перемещения: позволяет эффективно передавать временные объекты, минимизируя копирование данных.
- Оптимизация производительности: за счёт уменьшения количества ненужных копирований.
Lvalue-ссылки
Lvalue-ссылки в C++ имеют много общего с указателями и ссылками, но есть отличие: lvalue - подмножество ссылок, которые могут быть привязаны только к lvalue, а не rvalue.