Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the use of rvalue reference member variables

I was wondering if there is a point in having a rvalue reference variable (not as a function parameter)? I understand the use of rvalue reference when it is used as a function variable as then it is possible to avoid unnecessary allocations etc. But is there a use case rvalue reference variables that are not function parameters? Initially I thought that with such variables we could capture data that was passed in as rvalue for use later, but it seems that if we have a rvalue reference variable, then we can already take its address and therefore it can not be rvalue reference anymore.

I tried the following code and it ( unsurprisingly ) does not compile. So why would I ever want to have a rvalue reference variable?

void test(int&& a) {}

int&& a(22);
test(a);

Thanks!

like image 931
bim_bam Avatar asked May 17 '15 19:05

bim_bam


1 Answers

Your a here is the name of a rvalue reference. a itself is a lvalue (you can take its address) of type rvalue reference (yes, a bit confusing). So whenever you pass your a to test(a), you pass a lvalue. Think about lvalues as any object that has a name, or of which you can latter take its address. And you cannot bind a lvalue to a rvalue reference, hence the compile error

error: cannot bind 'int' lvalue to 'int&&'

You need to pass std::move(a). In this case, you cast away the lvalue-ness of a.

Note that inside your function a is also a lvalue (again, you can perform lvalue operations on it, like taking its address etc). You need a cast (std::move) anytime you want to use it as a rvalue. For example, say you have an object Bar with a member variable Foo member;, and you want to move into it via a member function f:

void Bar::f(Foo&& param)
{
    member = std::move(param); // need std::move here to move param into member
}

// invoked it as
bar.f(std::move(some_foo)); // move some_foo into param

If you don't cast param to a rvalue reference with std::move, then you don't move param into member, you just copy it (if param is copy-able, otherwise you get a compile-time error), since param itself is a lvalue. Hope this clarifies it.

like image 180
vsoftco Avatar answered Oct 10 '22 18:10

vsoftco