0Pricing
C++ Academy · Урок

Lvalue и rvalue: различие

Разбирайтесь в категориях значений: lvalue, prvalue и xvalue.

«Lvalue и rvalue: различие» — бесплатный урок C++ Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C++ Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C++ Academy содержит 4 уроков всего.

Два мира: левосторонние и правосторонние значения

Каждое выражение в C++ является либо левосторонним значением (объектом с именем и адресом), либо правосторонним значением (временным объектом без имени).

Левосторонние значения

Левостороннее значение обозначает постоянный объект — его адрес можно получить с помощью &.

int x = 42;           // x is an lvalue
int* p = &x;          // taking the address of an lvalue

int& r = x;           // r is an lvalue reference

Правосторонние значения

Правостороннее значение — это временный объект: литерал, возвращаемое функцией значение или выражение вроде a + b. Получить его адрес нельзя.

int a = 5, b = 3;
int c = a + b;        // (a + b) is an rvalue
// int* p = &(a + b); // ERROR: cannot take address of an rvalue

Почему это различие важно

Правостороннее значение скоро будет уничтожено. Мы можем безопасно забрать его ресурсы вместо копирования — на этом основана семантика перемещения.

Три категории начиная с C++11

Современный C++ уточняет эту модель:

  • левостороннее значение — имеет имя и идентичность
  • чистое правостороннее значение — полностью временный объект (литерал или значение, возвращаемое по значению)
  • истекающее значение — скоро будет уничтожено (результат std::move)

Ссылки на левосторонние и правосторонние значения

Ссылка на левостороннее значение использует &, а ссылка на правостороннее значение — &&.

int x = 10;
int&  lr = x;        // lvalue reference
int&& rr = 42;       // rvalue reference, binds to literal

Правила связывания

Совместимость типов:

  • ссылка на левостороннее значение (T&) связывается с левосторонними значениями
  • константная ссылка на левостороннее значение (const T&) связывается с обоими видами
  • ссылка на правостороннее значение (T&&) связывается только с правосторонними и истекающими значениями

Проверка с помощью decltype

С помощью decltype можно попросить компилятор определить категорию выражения.

int x = 10;
static_assert(std::is_lvalue_reference<decltype((x))>::value);
// the extra parentheses make decltype yield the lvalue ref

Зачем в C++11 добавили ссылки на правосторонние значения

Чтобы обеспечить семантику перемещения: конструктор, принимающий T&&, может забрать внутренние данные временного объекта, избежав глубокого копирования.

Распространённая ошибка: именованная ссылка на правостороннее значение — это левостороннее значение

После объявления переменная-ссылка на правостороннее значение получает имя, поэтому становится левосторонним значением. Чтобы передать её дальше как правостороннее значение, используйте std::move.

void f(std::string&& s) {
    // s here is an lvalue!
    process(std::move(s));   // now it is an rvalue again
}

Предварительный обзор идеальной передачи

Шаблоны, принимающие T&&, выводят либо ссылку на левостороннее, либо ссылку на правостороннее значение. В сочетании с std::forward они могут сохранять категорию значения — подробно это рассматривается далее.

Быстрая проверка

Какое из этих выражений является правосторонним значением?

Итоги

Левостороннее значение имеет имя и адрес, а правостороннее значение является временным. T& связывается с левосторонними значениями, а T&& — с правосторонними. Это различие обеспечивает семантику перемещения и позволяет избегать ненужного копирования временных объектов.

Часто задаваемые вопросы

Урок «Lvalue и rvalue: различие» бесплатный?

Да — полный текст урока «Lvalue и rvalue: различие» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C++ Academy, подпишись на CoddyKit PRO. Курс C++ Academy содержит 4 уроков всего.

Чему я научусь в уроке «Lvalue и rvalue: различие»?

Разбирайтесь в категориях значений: lvalue, prvalue и xvalue. Ты практикуешь C++ Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать C++ Academy?

Предыдущий опыт не требуется. C++ Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.

Сколько времени занимает урок «Lvalue и rvalue: различие»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке C++ Academy?

Да. Каждый урок C++ Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Lvalue и rvalue: различие
  2. Ссылки rvalue и синтаксис &&
  3. std::move и std::forward
  4. Конструкторы перемещения и присваивание перемещением
← Назад к C++ Academy