
Darren Cook ha escrito:
reverse is not a member function of indexed_set, but rather of sequenced indices. The line:
tc.reverse();
works because the indexed_set inherits the public interface of its first index. So this is but an abbreviation of:
tc.get<0>().reverse();
(This particular point of indexed_set inheriting index #0 interface has originated some perplexities in other readers.)
That is clever, but the potential for confusion far outweighs any benefit (IMHO). Do you have any strong supporters for the idea?
Not really, apart from me :) The idea is that the first index can be thought of as the *primary* index in some sense. So, the following indexed_set< int, index_list< unique<identity<int> >, sequenced<>
can be treated as a std::set with an aditional sequenced index, while indexed_set< int, index_list< sequenced<>, unique<identity<int> >
puts greater emphasis on the sequenced index, and its "default" interface is that of a std::list.
Now, reverse is a memfun of sequenced indices for the simple reason that it is also present in std::list (and sequenced indices mimic its interface as closely as possible.) As std::sets do not have a reverse operation, neither do regular indices (furthermore, this op does not make sense for such indices.)
I think the function makes sense: I can call reverse on the index then call some complex function that uses begin/end, to save having to write a rbegin/rend version. E.g. to process a list from oldest to youngest instead of youngest to oldest.
But you cannot have such a thing as a reverse op for regular indices. Think of std::sets: a reverse() memfun would alter the basic invariant of the set, namely that the elements are arranged in a definite order imposed by the comparison predicate. The same happens with regular indices. The complex function you talk about can be made more generic if it is templatized according to the iterator type, so that it accepts rbegin/rend as well as begin/end --admittedly, this might not be sufficient in some cases.
I also think the interface for regular and sequenced indices should be as close as possible, as I'm sure I'm going to want to write generic functions that take either type.
Ummm... the common subset of operations between regular and sequenced indices is currently: * operator=,get_allocator,empty,size,max_size, * (r)begin/(r)end, * erase,update,modify,clear,swap, The main differences are with respect to insertion, where semantics are very dissimilar (regular indices do have a definite ordering, not so sequenced indices.) Gotta think of it, maybe I can add the following to sequenced indices: insert(const value_type& x); insert(InputIterator first,InputIterator last); with the implied assumption that insertion takes place at the end of the index. This would provide of fair amount of interface commonality between regular and sequenced indices. Comments? Joaquín M López Muñoz Telefónica, Investigación y Desarrollo