Given a boost::container::vector<C> vec; I can write vec.push_back(move(value)) for a move-only (non-copyable) type C, instead of vec.push_back(value) as usual. But what would I write instead of vec.insert(pos,b,e) where (b,e] is a range of values? I'm particularly fond of Range concept, rather than loose iterators, so my function would be something that takes something that works as a Range; e.g. template <typename R> void prepend (const R& src_range) { auto b= boost::begin(src_range); auto e= boost::end(src_range); vec.insert(vec.begin(), b, e); } An rvalue reference to a range is not the same thing as a range of values that I may move from. I could have a differently named function and pass it a range with the implicit assumption that the function will modify the values, but is there a proper way to indicate that as part of the type? src_range can be, say, a pair of (non-const) iterator s as opposed to a pair of const_iterator s, or otherwise range_iterator<R>::type is dereferencable to a const value or not. But that itself is hard to see in general let alone overload against! If my function were called prepend_and_destroy_original(src) it might clue in the caller, but in general it is surprising that a parameter of (const R&) will modify the values. src itself doesn't change, and now refers to the same range of values which are now swapped out with defaults. With built-in pointers and even shared_ptr I can distinguish between an in-out parameter and a parameter that dereferences to a modifiable or const value. But what about with Ranges? Even with lower-case ranges provided by two iterators, How can you call something like boost::container::vector v2 (InIt_start, InIt_end); to convert a std::vector or some other container of move-only items? Only if the types match exactly can the vector(vector&&) constructor be used. —John