You can navigate from the list of initializers with a small number of templates.
template<class T> struct force_move{ mutable T t; template<class...Args> force_move(Args&&...args): t(std::forward<Args>(args)...) {}
Using:
std::vector<C> v=make_container<C>{ {}, {} };
It is concise, effective and solves your problem.
(Maybe it should be operator T&& above). Not sure, and I don't know, ever returning rvalue link ...)
Now it seems a bit hacked. But the alternatives suck.
The manual back back / emplace back list is ugly and becomes uglier after adding fallback requirements for maximum efficiency. And the naive solution il cannot move.
Solutions that do not allow you to list items right where the instance is declared are, in my opinion, inconvenient. You want the content list to be adjacent to the ad.
Another alternative to the โlocal listโ is to create a function variable that internally initializes std::array (possibly ref wrappers), which then moves from this array to the container. However, this does not allow style lists { {}, {}, {} } , so I miss.
We could do this:
template<class T, std::size_t N> std::vector<T> move_from_array( T(&arr)[N] ){ return {std::make_move_iterator(std::begin(arr)), std::make_move_iterator(std::end(arr))}; }
Then:
C arr[]={{}, {}, {}}; std::vector<C> v = move_from_array(arr);
The only drawback is the two statements at the point of use. But the code is less dumb than my first decision.