Почему 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
параметр является ссылкой для пересылки.