In the code below, why doesn't the first call mkme = mvme_rv
dispatch to T& operator=(const T&&)
?
#include <iostream>
#include <string>
#include <vector>
using namespace std;
using T = vector<int>;
int main()
{
T mvme(10, 1), mkme;
T&& mvme_rv = move(mvme); // rvalue ref?
mkme = mvme_rv; // calls T& operator=(const T&)?
cout << mvme.empty(); // 0
mkme = move(mvme_rv); // calls T& operator=(const T&&)?
cout << mvme.empty(); // 1
}
Rvalue references is a small technical extension to the C++ language. Rvalue references allow programmers to avoid logically unnecessary copying and to provide perfect forwarding functions. They are primarily meant to aid in the design of higer performance and more robust libraries.
If you want pass parameter as rvalue reference,use std::move() or just pass rvalue to your function.
In the example, the main function passes an rvalue to f . The body of f treats its named parameter as an lvalue. The call from f to g binds the parameter to an lvalue reference (the first overloaded version of g ). You can cast an lvalue to an rvalue reference.
2) non-modifiable lvalues, which are const. rvalue — The expression that refers to a disposable temporary object so they can't be manipulated at the place they are created and are soon to be destroyed. An address can not be taken of rvalues. An rvalue has no name as its a temporary value.
As skypjack correctly comments, accessing an object through its name always results in an lvalue reference.
This is a safety feature and if you think it through you will realise that you are glad of it.
As you know, std::move
simply casts an l-value reference to an r-value reference. If we use the returned r-value reference immediately (i.e. un-named) then it remains an r-value reference.
This means that the use of the r-value can only be at the point in the code where move(x)
is mentioned. From a code-reader's perspective, it's now easy to see where x's state became undefined.
so:
1: auto x = make_x();
2: auto&& r = std::move(x);
3: // lots of other stuff
35: // ...
54: // ...
55: take_my_x(r);
does not work. If it did, someone maintaining the code would have a hard time seeing (and remembering) that x (defined on line 1) enters an undefined state on line 55 through a reference taken on line 2.
This is a good deal more explicit:
1: auto x = make_x();
2: //
3: // lots of other stuff
35: // ...
54: // ...
55: take_my_x(std::move(x));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With