std::move doesn't move?

Hi,
I am following an example from Stroustrup's book, where we have a vector called v below which is passed by reference to function user(). There, it is passed to do_task() but as an rvalue thanks to std::move. The idea was that after the call to do_task, the vector large would be now empty but it isn't!! (since it was MOVED)...

void do_task(std::vector<int>&&v) {

}

std::vector<int> user(std::vector<int>& large) {
std::vector<int> res;

do_task(std::move(large)); // TRANSFERRING OWNERSHIP OF DATA TO do_task?

return res;
}

void intoChapter31() {

std::vector<int> v{2,6,8,99,234,564,788,901};
auto r = user(v);
}

thanks!!
Juan
std::move doesn't move?

No, it doesn't. It returns a type that may be moved from (an rvalue reference) and that is all it does.

The idea was that after the call to do_task, the vector large would be now empty but it isn't!! (since it was MOVED)...

http://crascit.com/2015/09/21/when-moving-doesnt-move/
Ok, I found something else: we don't need do_task to receive an rvalue reference in order for allowing movement. I found this works:

void do_task(std::vector<int>&v) {
std::vector<int> s { std::move(v) };
}

So there is no need to call do_task with a move(large) parameter...as long as do_task receives the vector by reference, it does not care if it is an lvalue reference or rvalue reference...

Where move NEEDs to be used is in the v parameter inside do_task when we want to move it to a local vector (the original intention), like the code for do_task above...

so, calling do_task with move(large) is misleading because there is no guarantee that the parameter will be moved... Then why use move there?


Thanks
Juan
If do_task has the prototype: void do_task(std::vector<int>& v), there is no way to know if moving from v is safe inside the function, so you should not do so.

std::move says "Hey compiler, I don't care what is in v after I use it here", but you have no idea if the code calling do_task does.

In this case the correct thing to do would be for do_task to take the vector by value, the the calling code can say:

1
2
 do_task(v);  // make a copy, I'm not done with v, or...
 do_task(std::move(v)); // I don't care what the contents of v is after the call. 


Where move needs to be used is in the code that knows if it wants to preserve the value of the vector or not.



got it!!

Just one thing, do_task does not necessarily need to receive the vector by value, by lvalue reference would be okay - maybe const std::vector<int>& v.
Then we overload another do_task for receiving an rvalue reference, as you have so clearly explained.

Do you agree with this? I am just trying to avoid copying the vector if all we desire is to ensure it will not be modified inside do_task...


Thank you!!!
Juan
Do you agree with this? I am just trying to avoid copying the vector if all we desire is to ensure it will not be modified inside do_task...

If there is no reason to copy it... why would there be a reason to move it?
Topic archived. No new replies allowed.