Почему std::move принимает ссылку на rvalue в качестве аргумента?

Согласно cppreference.com, move имеет подпись

template< class T >
typename std::remove_reference<T>::type&& move( T&& t ) noexcept;

Почему требуется ссылка? T&& t как его аругмент?

Также, когда я попробовал следующий код

void foo(int&& bar) {
    cout << "baz" << endl;
}

int main(){
    int a;
    foo(a);
}

Я получил ошибку от компилятора "ссылка на rvalue не может быть привязана к lvalue"

Что здесь происходит? Я весьма озадачен.

1 ответ

Решение

Это не ссылка на значение, а ссылка на пересылку; который может сохранить категорию значения аргумента. Это означает std::move может принимать как lvalue, так и rvalue и безоговорочно преобразовывать их в rvalue.

Пересылка ссылок - это особый вид ссылок, которые сохраняют категорию значений аргумента функции, позволяя пересылать ее с помощью std::forward. Пересылочные ссылки:

1) параметр функции шаблона функции, объявленный как rvalue ссылка на параметр шаблона cv-unqualified типа того же самого шаблона функции:

2) auto && за исключением случаев, когда они выводятся из списка инициализаторов, заключенного в фигурные скобки.

С другой стороны, int&& является ссылкой на значение; обратите внимание на разницу здесь, если параметр шаблона функции имеет тип T&& с параметром шаблона T т.е. выводимый тип T параметр является ссылкой для пересылки.

Другие вопросы по тегам