
David, Thank you for your answer. I fully respect that you don't want to spend any more time on an idea that you don't like and don't believe in, so I don't really expect you to respond to this post, but I still want to comment on the technical point you make in case somebody else is reading this thread, now or in the future.
David Abrahams wrote:
It took me about 3 seconds to notice that your iterator is broken in another way: it assumes the operators on the underlying iterators are implemented as member functions and not free functions.
Christian Engström <christian.engstrom@glindra.org> writes:
Good point, but again it relates to the draft implementation, and not to the underlying design.
Suggestion: ask yourself why this objection is an implementation detail, while the inability to "proxy-ize" a pointer is not. Both are soluble problems.
The reason why I consider them different is that the objection about the operators as member functions is trivial to correct (once the flaw has been pointed out, which is less trivial), by just modifying the respective member function bodies in the proxy iterators. The inability to proxy-ize a pointer, on the other hand, is due to the fact that the proxy iterators are derived from the underlying iterators, which of course rules out raw pointers. The reason why they are derived, in turn, is that we want the proxy iterators and the underlying "normal" iterators to be implicitly convertable to each other in both directions. If both conversions were user defined, as they would have to be if the proxy iterators could not utilize the implicit derived-to-base conversion, this would lead to a host of ambiguity problems, since the compiler has no reason to prefer one conversion over the other. The classic example is the expression a == b, which becomes ambiguous because the compiler is just as happy to carry out the comparison as either b_type(a) == b or a == a_type(b) if both conversions are available as implicit user defined conversions, and there is no == operator defined for the mixed types case. If one of the conversions is instead a derived-to-base conversion and the the other is user defined, the compiler will prefer the derived-to-base conversion, so there is no ambiguity. Even if the particular example of the == operator can be handled by using the excellent boost/operators.hpp package to define a mixed type == operator, it will at the very least introduce a new level of complexity into the design, even if it were to turn out to be possible to handle the ambiguity problem in general by going further along this route. For this reason I prefer to accept the limitation that the container adaptor can only be used with STL compatible containers that implement the iterators as classes rather than as raw pointers. If someone can demonstrate an amended design that works with raw pointers as well, that might of course be even better, but even without that generalization, I think that an adaptor that works on the many containers that do in fact have class iterators still covers a quite respectable domain, so I don't see it as an absolute necessity to expand it any further. /Christian