Search code examples
c++smart-pointersinitializer-list

Initialize a vector with unique_ptr in C++ within constructor


I am new to C++, and after having read A LOT about move semantics and unique pointers (and initializer lists), I get why this code won't work (throwing "attempting to reference a deleted function"):

term_array::term_array(std::unique_ptr<term>&& opd) 
    : term(std::vector<std::unique_ptr<term>> {std::move(opd)}) {...}

It's a constructor intended to pass a pointer opd (pointing to a term object) on from a derived class term_array to the base class term, where the term constructor expects a vector or pointers. Therefore, I tried to create a std::vector<std::unique_ptr<term>> on the fly and fill it with the one opd pointer received from the term_array constructor. Obviously, this doesn't work since a unique_ptr cannot be copied, and the initializer_list initialization won't allow a move operation.

I saw in this question how to "list-initialize a vector of move-only type" in regular program flow (meaning when you can use several lines of code). But (how) can this be done within a simple constructor call? Or am I completely off-track?


Solution

  • You can do this with a helper function template:

    template <class T>
    auto SingletonVector(T&& x) {
        std::vector<std::decay_t<T>> ret;
        ret.push_back(std::forward<T>(x));
        return ret;
    }
    

    Then:

    term_array::term_array(std::unique_ptr<term>&& opd) 
    : term(SingletonVector(std::move(opd))) {...}