Ответ
lvalue (left-hand value) — это выражение, которое обозначает объект, занимающий идентифицируемое место в памяти (т.е. имеющий адрес). Его время жизни выходит за рамки одного выражения. Ключевое свойство lvalue — к нему можно применить оператор взятия адреса &.
Характеристики и примеры lvalue:
- Имена переменных (как фундаментальных, так и пользовательских типов).
int x = 42; // `x` — lvalue std::vector<int> vec; // `vec` — lvalue - Ссылки всегда являются lvalue.
int& ref_x = x; // `ref_x` — lvalue (ссылается на `x`) - Результат обращения к элементу по индексу или имени, если контейнер возвращает ссылку.
vec[0] = 10; // `vec[0]` — lvalue (operator[] у std::vector возвращает T&) - Разыменованный указатель.
int* ptr = &x; *ptr = 100; // `*ptr` — lvalue - Строковые литералы (в C++ они имеют тип
const char[N]и хранятся в памяти).const char* p = "hello"; // `"hello"` — lvalue - Функции. Имя функции — lvalue.
Важное уточнение: lvalue не обязательно может находиться слева от оператора присваивания. Константные lvalue (const int c = 5;) являются неизменяемыми.
Практическое значение: Понимание категорий значений (lvalue, rvalue, xvalue, prvalue, glvalue) критически важно для:
- Работы с ссылками: Невозможно инициализировать неконстантную lvalue-ссылку (
int&) rvalue.int& a = 10; // Ошибка: 10 — rvalue const int& b = 10; // OK: const lvalue-ссылку можно биндить к rvalue - Использования семантики перемещения: Правила выбора перегруженных функций (принимающих
T&илиT&&) основаны на категории передаваемого выражения. - Оптимизаций: Компилятор может применять разные оптимизации в зависимости от того, является ли выражение lvalue.