Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rvalue reference: Why aren't rvalues implicitly moved?

On Artima article about C++ rvalue reference (http://www.artima.com/cppsource/rvalue.html) there is words: That's why it is necessary to say move(x) instead of just x when passing down to the base class. This is a key safety feature of move semantics designed to prevent accidently moving twice from some named variable.

I can't think situation when such double move can perform. Can you give an example of this? In other words, what will go wrong if all members of T&& would be rvalue references and not just references?

like image 461
demi Avatar asked Jan 16 '13 05:01

demi


People also ask

Are rvalue references Lvalues?

lvalue references are marked with one ampersand (&). And an rvalue reference is a reference that binds to an rvalue. rvalue references are marked with two ampersands (&&). Note that there is one exception: there can be lvalue const reference binding to an rvalue.

Can rvalue bind to lvalue?

By default, the compiler cannot bind a non-const or volatile lvalue reference to an rvalue.

Why do we need move semantics?

Move semantics allows you to avoid unnecessary copies when working with temporary objects that are about to evaporate, and whose resources can safely be taken from that temporary object and used by another.

How do you pass rvalue reference to a function?

If you want pass parameter as rvalue reference,use std::move() or just pass rvalue to your function.


1 Answers

Consider this scenario:

void foo(std::string x) {}
void bar(std::string y) {}

void test(std::string&& str)
{
    // to be determined
}

We want to call foo with str, then bar with str, both with the same value. The best way to do this is:

foo(str); // copy str to x
bar(std::move(str)); // move str to y; we move it because we're done with it

It would be a mistake to do this:

foo(std::move(str)); // move str to x
bar(std::move(str)); // move str to y...er, except now it's empty

Because after the first move the value of str is unspecified.

So in the design of rvalue references, this implicit move is not there. If it were, our best way above would not work because the first mention of str would be std::move(str) instead.

like image 69
GManNickG Avatar answered Oct 20 '22 01:10

GManNickG