lundi 27 juillet 2015

Moving a container's elements

My understanding of move semantics is that you should declare the function's parameters as by-value but make a call to std::move when you are interested in owning an object. This lets the compiler decide if the object should be copied or moved.

How do you allow the compiler to make a similar optimization when you are only interested in the object's contents, without making unnecessary copies of the container or it's elements. So for example if I have some function which takes an array of 3 objects and stores them in it's own container, how do I let the compiler decide if it should move or copy the elements?

class foo {
    std::vector<BigObject> objects;

public:
    void set_objects(std::array<BigObject, 3> input) {
        // Store the input's elements in the objects vector
    }
};

I read about std::make_move_iterator but I am unsure whether this forces a move and how this effects the input or how the input parameter should be defined.

For example if set_objects's body looked like so:

objects = std::vector<BigObject>(
    std::make_move_iterator(input.begin()),
    std::make_move_iterator(input.end())
);

I believe objects would now be a vector containing input's elements and input would now be empty. That's desired if input was an xvalue but the signature declares input as by-value so was the original container copied even if it was an xvalue as nowhere do I say to move the actual container, just it's elements.

I can declare input as by-reference to prevent the copying but then if std::make_move_iterator forces a move there could be side effects if input was an lvalue?

Having typed out my question I believe the answer is to overload set_objects with an xvalue and by-reference signature, the former moving input's elements and the later copying input's elements but I do not feel confident enough to say that is the correct solution.

Aucun commentaire:

Enregistrer un commentaire