I understand that if you want a vector of unique_ptr then you need to use vector.push_back( move(myPtr) ) as a unique_ptr is not copyable. However, I'm struggling to create a vector of queues of unique_ptr:
1 2 3 4 5 6 7
using MsgPtr = std::unique_ptr<int>;
using MsgQueue = std::queue<MsgPtr>;
std::vector<MsgQueue> mMsgQueues;
MsgQueue myQueue;
mMsgQueues.push_back( std::move(myQueue) );
gives the following error:
1 2 3
/usr/include/c++/7/bits/stl_construct.h:75:7:
error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&)
[with _Tp = int; _Dp = std::default_delete<int>]’
The standard library's container adapters do not play well with move-only types. Further, their move constructors are unconditionally potentially-throwing which is problematic for other reasons.
My solution in practice has been to avoid container adapters entirely. You could rely on a better library implementation.
If this isn't an option, one potential approach is to inherit from std::queue<T> and store the derived class type instead, as follows:
I didn't say what the problem is, so I'll do that now. vector::push_back instantiates the move constructor for its value type if and only if the value type either
a.) provides a non-throwing move constructor; or
b.) does not provide a copy constructor at all.
Otherwise, it instantiates the copy constructor.
queue<unique_ptr>'s move constructor is potentially-throwing, and its copy constructor is present. As such std::vector dutifully follows the rules above and tries to instantiate queue<unique_ptr>'s copy constructor, which results in a hard error.
It may be easier to switch internally to shared_ptr<const T> (which is copyable) at some runtime cost.
Or, you could maybe give the polymorphic object a copyable wrapper.