
David Abrahams writes:
"Robert Ramey" <ramey <at> rrsd.com> wrote in message news:cmrl55$hng$1 <at> sea.gmane.org...
I agree that iterators aren't that easy or intuitive to work with. So
our
motivations have much in common. My view is that iterators can be made easier to work with without changing their fundamental character and without the need to introduce what I see as a new concept (ranges) that is "almost the same" as an existing concept - pair of iterators.
Like Robert I am uncomfortable with a range concept that has iteration capabilities. For one thing, standard containers don't satisfy that concept, and it seems to me that a container ought to be a range without any special adaptation. Furthermore I have doubts about how well this "range/iterator" concept maps onto bidirectional and random access. That said...
I think it will be very difficult to have the standard containers satisfy a range concept. Containers hold elements, and provide access to them via iterators. Those two iterators model a range. Algorithms like for_each take that range, and process the items element by element, by using the first element, and shrinking the range by incrementing the first iterator. When you view a container as a range, you can't shrink the range without deleting elements. This would mean that when passing a container to an algorithm that that algorithm either deletes items or has to copy the container. Ranges live at the level of iterators, providing access. They do not live at the level of containers, which store elements. Therefore, I think a container does not need to satisfy the range concept. If I were allowed to make changes to the standard library, I would add a member function range() to containers, returning some range object holding a begin and an end: Containers hold objects, and provide access to them by representing those objects as a range. The range provides access to individual elements using iterators. Of course, changes to the standard library are not considered here. A make_range(container), however, comes very close to this, and seems like a good solution to me. As to the iteration capabilities: What would we loose if the iteration capabilities are removed? Are for-loops the only place that would be significantly changed? for ( crange<some_array_type> r(some_array); r; ++r) do_something( *r, some_data); I think this syntax is a bit too short anyway. What about adding member functions empty(), size(), front(), back()? for ( crange<some_array_type> r(some_array); !r.empty(); ...) do_something( r.front(), some_data); Looks nice enough, IMHO. This leaves only the problem of shrinking the range at the start. What do you think about range.begin() (non-const version) returning a reference to its begin iterator? Then ++r.begin() would be the equivalent of the current ++r. Similarly end() can return a reference, making shortening the range at the end possible. Another option I thought of was using pop_front(), but this has the disadvantage that it doesn't do exactly what is says: it does resemble list's pop_front, but no element is really erased. best regards, Richard Peters