Boost logo

Boost :

From: Christian Engström (christian.engstrom_at_[hidden])
Date: 2004-02-24 07:07:52


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_at_[hidden]> 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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk