Search code examples
c++c++11move-semanticsunique-ptrdeleted-functions

'use of deleted function' when merging two vectors of unique_ptr


I'm trying to merge two vectors of unique_ptr (i.e. std::move them out from one and into another) and I keep running into a "use of deleted function..." wall of error text. According to the error, I am apparently trying to use unique_ptr's deleted copy constructor, but I'm not sure why. Below is the code:

#include <vector>
#include <memory>
#include <algorithm>
#include <iterator>

struct Foo {
    int f;

    Foo(int f) : f(f) {}
};

struct Wrapper {
    std::vector<std::unique_ptr<Foo>> foos;

    void add(std::unique_ptr<Foo> foo) {
        foos.push_back(std::move(foo));
    }

    void add_all(const Wrapper& other) {
        foos.reserve(foos.size() + other.foos.size());

        // This is the offending line
        std::move(other.foos.begin(), 
                  other.foos.end(), 
                  std::back_inserter(foos));
    }
};

int main() {
    Wrapper w1;
    Wrapper w2;

    std::unique_ptr<Foo> foo1(new Foo(1));
    std::unique_ptr<Foo> foo2(new Foo(2));

    w1.add(std::move(foo1));
    w2.add(std::move(foo2));

    return 0;
}

Solution

  • You're trying to move from a constant Wrapper object. Generally move semantics also require the object you are moving away from to be mutable (i.e. not const). In your code the type of the other parameter in the add_all method is const Wrapper&, therefore other.foos also refers to a constant vector, and you can't move away from it.

    Change the type of the other parameter to Wrapper& to make it work.