3

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?

Duke
  • 410
  • 7
  • 15
  • 1
    Perhaps you should worry less about move semantics and unique pointers, and more about writing a useful application in C++. Have you done that yet? –  May 30 '18 at 22:42
  • That's what I'm trying to do. I want to write a small program to evaluate arithmetic expressions. `term` is supposed to be an abstract base class for operations, holding a vector of operands (terms themselves), hence the vector of unique_ptr. The derived classes should implement the actual various behaviors of plus, minus, mult etc. Is this a bad way to approach that? – Duke May 30 '18 at 23:07

1 Answers1

3

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))) {...}
Brian Bi
  • 111,498
  • 10
  • 176
  • 312
  • Still trying to figure this out... Can you please tell me why you called the function `SingletonVector`? I don't see a "singleton" (as I know it) being involved here. I also don't get why you use `std::decay_t` - isn't `x` an rvalue reference anyway, so decay should not have an effect (according to [the C++ reference](http://www.cplusplus.com/reference/type_traits/decay))? – Duke May 31 '18 at 07:10
  • 1
    @Duke a singleton is a set that contains one element. `x` is a forwarding reference, so `T` may be deduced to an lvalue reference if an lvalue is passed in. `decay_t` is used to remove both the reference and any cv-qualifiers that `T` may carry. – Brian Bi May 31 '18 at 21:43
  • 1
    Thanks a lot! And sorry for the stupid questions... C++ is pretty hard when coming from Java... I'm not even sure `unique_ptr` is the best pointer type for what I want to do. It all seems so clumsy... – Duke Jun 01 '18 at 06:53