Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does std::move take rvalue reference as argument?

According to cppreference.com, move has signature

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

Why does it take a rvalue reference T&& t as its arugment?

Also when I tried the following code

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

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

I got an error from the compiler "an rvalue reference cannot be bound to an lvalue"

What is going on? I'm so confused.

like image 331
Shawn Li Avatar asked Dec 17 '17 05:12

Shawn Li


1 Answers

It's not an rvalue reference, but a forwarding reference; which could preserve the value category of the argument. That means std::move could take both lvalue and rvalue, and convert them to rvalue unconditionally.

Forwarding references are a special kind of references that preserve the value category of a function argument, making it possible to forward it by means of std::forward. Forwarding references are either:

1) function parameter of a function template declared as rvalue reference to cv-unqualified type template parameter of that same function template:

2) auto&& except when deduced from a brace-enclosed initializer list.

On the other hand, int&& is an rvalue reference; note the difference here, if a function template parameter has type T&& with template parameter T, i.e. a deduced type T, the parameter is a forwarding reference.

like image 108
songyuanyao Avatar answered Sep 21 '22 02:09

songyuanyao