I would like to implement a function that fills up a vector and then returns an rvalue reference. I tired something like:
std::vector<int> &&fill_list() {
std::vector<int> res;
... do something to fill res ...
return res;
}
int main(int argc, char **argv) {
std::vector<int> myvec = fill_list();
return 0;
}
but that doesn't work, I get the following error:
error: invalid initialization of reference of type 'std::vector<int>&&' from expression of type 'std::vector<int>'
So, all in all, how is the right way of doing it? I don't think I get rvalue references just yet.
Best Answer
You seem to be confused as to what an rvalue reference is and how it relates to move semantics.
First thing's first:
&&
does not mean move. It is nothing more than a special reference type. It is still a reference. It is not a value; it is not a moved value; it is a reference to a value. Which means it has all of the limitations of a reference type. Notably, it must refer to a value that still exists. So returning a dangling r-value reference is no better than returning a dangling l-value reference."Moving" is the process of having one object claim ownership of the contents of another object. R-value references facilitate move semantics, but simply having a
&&
does not mean anything has moved. Movement only happens when a move constructor (or move assignment operator) is called; unless one of those two things is called, no movement has occurred.If you wish to move the contents of a
std::vector
out of your function to the user, you simply do this:Given this usage of
fill_list()
:One of two things will happen. Either the return will be elided, which means that no copying or moving happens.
res
is constructed directly intomyvec
. Orres
will be moved into the return value, which will then perform move-initialization ofmyvec
. So again, no copying.If you had this:
Then again, it would be moved into. No copying.
C++11 knows when it's safe to implicitly move things. Returning a value by value rather than by reference or something is always a safe time to move. Therefore, it will move.