Skip to the content.

rvalue-ссылки и std::move()


Файл заголовков: #include <utility>

Для начала стоит вспомнить что выражения в С++ можно поделить на два типа:

Указатели могут указывать только на lvalue!

Начиная с С++11 ссылки тоже бывают двух видов:

Преобразование ссылок в шаблонах

До стандарта С++11 если в результате инстанцирования шаблона получался тип, который являлся ссылкой на ссылку то это приводило бы к ошибке компиляции. В С++11 появились правила “склейки”.

Правила “склейки” ссылок:

Таким образом можно создать универсальную ссылку:

template<typename T>
void foo(T && t) {}

Если передать функции:

std::move

std::move() это шаблонная функция, которая определена в стандартной библиотеке.

Упрощенное определение std::move():

template<class T>
typename remove_reference<T>::type&& move(T && a)
{
    typedef typename remove_reference<T>::type&& RvalRef;
    return static_cast<RvalRef>(a);
}

1. std::move шаблонная функция, которая принимает rvalue-ссылку, соответственно удовлетворяет требованиям универсальной ссылки

2. Возвращаемый тип:

Если бы мы сразу приводили lvalue-ссылку к rvalue-ссылке, то по правилам склеивания получили бы lvalue-ссылку (A& && -> A&).

Получается все что делает std::move() - static_cast lvalue к rvalue