Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it useless to declare a local variable as rvalue-reference, e.g. T&& r = move(v)?

Could you guys give me an illustrative example under certain circumstance to prove the following statements are useful and necessary?

AnyTypeMovable   v; AnyTypeMovable&& r = move(v); 
like image 526
xmllmx Avatar asked Sep 12 '13 13:09

xmllmx


People also ask

Can we take address of rvalue?

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.

Is an rvalue reference an Xvalue?

To answer the titular question, "rvalue reference" is a kind of type, while "xvalue" is a kind of expression. They are not. Rvalue references are types, types are not expressions and so cannot be "considered lvalue".

What is rvalue reference stackoverflow?

rvalue reference and lvalue reference are categories of references. Inside a declaration, T x&& = <initializer expression> , the variable x has type T&&, and it can be bound to an expression (the ) which is an rvalue expression. Thus, T&& has been named rvalue reference type, because it refers to an rvalue expression.

Where is rvalue stored?

R-value: r-value” refers to data value that is stored at some address in memory. A r-value is an expression, that can't have a value assigned to it, which means r-value can appear on right but not on left hand side of an assignment operator(=).


1 Answers

No, AnyTypeMovable&& r = move(v); here is not useful at all.

Consider the following code:

#include <iostream> #include <vector>  class MyMovableType {         int i; public:         MyMovableType(int val): i(val){}         MyMovableType(MyMovableType&& r) { this->i = r.i; r.i = -1; }         MyMovableType(const MyMovableType& r){ this->i = r.i; }         int getVal(){ return i; } };  int main() {         std::vector<MyMovableType> vec;         MyMovableType a(10);         MyMovableType&& aa = std::move(a);          vec.push_back(aa);          std::cout << a.getVal() << std::endl;          return 0;  } 

As aa is an l-value (as noted by R. Martinho Fernandes, and also by Xeo - a named rvalue-reference is an lvalue), this will print 10 indicating that moving has not been performed (nor in the assignment, nor in the push_back call), so you still need to std::move it to the push_back method, as in this case:

#include <iostream> #include <vector>  class MyMovableType {         int i; public:         MyMovableType(int val): i(val){}         MyMovableType(MyMovableType&& r) { this->i = r.i; r.i = -1; }         MyMovableType(const MyMovableType& r){ this->i = r.i; }         int getVal(){ return i; } };  int main() {         std::vector<MyMovableType> vec;         MyMovableType a(10);         MyMovableType&& aa = std::move(a);          vec.push_back(std::move(aa));          std::cout << a.getVal() << std::endl;          return 0;  } 

move will be performed, so the printout will be -1. So, despite the fact that you're passing aa to the push_back, you still need to pass it via std::move.

like image 175
Nemanja Boric Avatar answered Sep 18 '22 11:09

Nemanja Boric