0

I'm trying to efficiently pass a big vector to an object constructor, then empty it and finally re-use it. I wrote this solution:

template<typename T>
struct vect_obj{
    vect_obj(vector<T> &&v) : v(move(v)) {}
    vector<T> v;
};

int main()
{
    vector<int> v(10,1);
    //v.size()=10
    vect_obj<int> v_o (move(v));
    //v.size()=0
    v.push_back(10);
    //v.size()=1
}

But:

  1. Even if it works, I'm not sure if it's a good practice/correct way.
  2. Not sure if it's efficient (reason why I'm using move).
justHelloWorld
  • 6,478
  • 8
  • 58
  • 138
  • As soon as you `move(v)` you can no longer `v.push_back(10);` because you just relinquished ownership of that vector to `vect_obj`, so `v` is now garbage. – Cory Kramer Jan 08 '16 at 17:43
  • 4
    @CoryKramer: `v` is not garbage. It's valid but unspecified. – Nicol Bolas Jan 08 '16 at 17:43
  • 1
    @NicolBolas thanks for your answer. I don't understand the "unspecified" state: it isn't `NULL` (in fact I can `push_back`) but I don't understand what happens to `v` after `move` – justHelloWorld Jan 08 '16 at 17:47
  • Define "valid", @NicolBolas? moved-from objects must be destructible. And I think that, in some cases, they must be assignable. But I don't think there is a requirement that `push_back` be callable (before assigning) – Aaron McDaid Jan 08 '16 at 17:48
  • @AaronMcDaid: No, you can't call `push_back`, as this requires it to be in a specific state (like containing things). But you can call functions that don't require it to be in a state, like `clear`. – Nicol Bolas Jan 08 '16 at 17:55
  • @NicolBolas I'm sorry, but if I've understood correctly, you're saying that `v.push_back` will crash the program...Which actually doesn't (tested here http://goo.gl/X6px2V) – justHelloWorld Jan 08 '16 at 18:00
  • @justHelloWorld, I think the short answer is *"just don't use an object after calling `move` on them. They're none of your business any more."* Can you say more about the real problem you're working on. Why do you want to 'reuse' an object after calling 'move' on it? – Aaron McDaid Jan 08 '16 at 18:01
  • @AaronMcDaid I'm using it as buffer. When a certain number of elements are inserted, a `message` object is created: I pass `move(v)` to `message`'s constructor (so now `v`) is empty and the process is repeated. – justHelloWorld Jan 08 '16 at 18:06
  • 1
    @justHelloWorld: I didn't say it would *crash* anything. "Undefined behavior" includes the possibility of it working fine. That's why it's so pernicious; because it might work today, and fail tomorrow. You need to reset the vector to a known state, and calling `clear` has no preconditions. – Nicol Bolas Jan 08 '16 at 18:10
  • Use `swap` instead. `vect_obj v_o; v_o.swap(v);`. It's a clearer way to do what you want. Remember, `move` doesn't mean that the vector *will* be emptied. It just gives *permission* to the compiler to modify the source vector. It might even be very slow. But `slow` is fast, easy-to-read, and doesn't require c++11. – Aaron McDaid Jan 08 '16 at 18:23

0 Answers0