Что такое lvalue в C++?

«Что такое lvalue в C++?» — вопрос из категории C++ Core, который задают на 30% собеседований C/C++ Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

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) критически важно для:

  1. Работы с ссылками: Невозможно инициализировать неконстантную lvalue-ссылку (int&) rvalue.
    int& a = 10; // Ошибка: 10 — rvalue
    const int& b = 10; // OK: const lvalue-ссылку можно биндить к rvalue
  2. Использования семантики перемещения: Правила выбора перегруженных функций (принимающих T& или T&&) основаны на категории передаваемого выражения.
  3. Оптимизаций: Компилятор может применять разные оптимизации в зависимости от того, является ли выражение lvalue.