I am writing some container or iterable-based algorithms. Basically, I operate on objects that support
for( : ) style iteration (I rarely use
for( : ) directly, but follow how it looks up the
std library, most every iterable objects are containers. They both own their data, and they let you look at it.
When an algorithm takes a container by rvalue reference, this implies that the contents of the container are also free to be taken from. As an example, if I write
concatinate which takes two
vectors and returns a third, if both
moved, we will want to reuse the first
vector then use
move_iterators to take the data out of the second
vector for efficiencies sake.
However, with C++1y's
string_view and types that are similar in conception, we have iterable objects that are not containers, but rather views into containers. Semantically, I believe views behave like pointers, so their "by-value" duplication is duplication of the view into the container, not the data they refer to. If I take a
string_view style view by rvalue reference, that doesn't mean it owns the contents: moving from the contents is not justified, no more than moving the contents of a pointer just because the pointer itself is an rvalue.
Meanwhile, containers follow value semantics, and moving their contents because they are an rvalue is valid.
string_view this isn't a problem, but I have written more generic
view classes, such as
contiguous_range_view, which lets you act on subsets of a
arr as if it was a non-mutable sized buffer.
These views do not always treat their contents as
const, but they do not own their contents. So the view being an rvalue does not imply that their contents are rvalues!
My algorithms like
concatinate run into problems here. Views are nearly indistinguishable from containers, and rvalue containers are valid to be moved-from, while rvalue views are not. And a function that returns a view by value is a good pattern, as views are semantically pointer-types.
I'm looking for a nice, clean way to distinguish between containers and views. Is there a plan to distinguish
string_view in C++1y through some property or tag that I could emulate or hook into now? If not, is there a good pattern?
If I manage to block views from being moved-from accidentally, I will still need to be able to move from them sometimes, so I'll need a way to mark a view as being a move-from candidate other than being an rvalue reference. I suspect a
make_move_range function might solve that problem (that takes an iterable range, and applies