2

Is it okay to do the following? The following code is using the vector v again in the loop (next iteration) after moving it.

#include <iostream>
#include <string>
#include <vector>

using namespace std;

void test(vector<int>&& v) {
    cout << v.size() << endl;
    v.push_back(5);
}

void test2(vector<int>& v) {
    for (int i = 0; i < 4; i++) {
        test(move(v));
    }
}

int main()
{
    vector<int> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    v.push_back(4);
    test2(v);    
}
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
M K
  • 356
  • 3
  • 8
  • `std::move` does not move anything, it's just a type conversion. It's probably the most misleading name in the entire standard. – molbdnilo May 22 '21 at 05:28
  • @molbdnilo ...but is neat. `std::as_rvalue` has five extra keystrokes – MatG May 22 '21 at 18:17
  • Does this answer your question? [Reusing a moved container?](https://stackoverflow.com/questions/9168823/reusing-a-moved-container) – Cameron May 23 '21 at 01:50

2 Answers2

3

Your code is correct, but the intention that you are communicating is wrong.

If someone sees the declaration of function test he will think that when calling the function he is giving away the ownership of the variable that he is passing, because the variable will be moved.

In general, after a call to std::move(v) you should not reuse v.

What you should do in this case is declare test as void test(std::vector<int>& v) and you should call it just with test(v). In this way it is clear that test will modify v, but you will be able to use it later.

Dundo
  • 714
  • 8
  • 12
  • 2
    In general, after a call to `std::move(v)`, `v` is in a valid but indeterminate state. https://stackoverflow.com/a/9168917/21475 – Cameron May 23 '21 at 01:50
2

std::move just converts argument passed to rvalue, but doesn't perform move operation itself.

Given test(move(v));, std::move converts v to rvalue, which gets bound to reference parameter v (so it refers to the parameter v of test2, i.e. the object v defined in main). No new vector object is constructed, and no move constructor or move assignment operator is called.

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
  • Yes, no move because `test()` doesn't construct another object (however I had to test it with an [example](https://gcc.godbolt.org/z/ch9qP4rzs) because I'm always wary about these things) – MatG May 22 '21 at 18:41