Iterator class for vector and basic_string
Oleg Zabluda
zabluda@math.psu.edu
Mon Nov 2 20:09:00 GMT 1998
Nathan Myers <ncm@cygnus.com> wrote:
: Oleg wrote:
: > Nathan Myers <ncm@cygnus.com> wrote:
: > : Oleg Zabluda wrote:
: > : > Ryszard Kabatek <rysio@rumcajs.chemie.uni-halle.de> wrote:
: > : > : I wrote an iterator class for std::vector<> and std::basic_string<>.
[...]
: > : > : template<typename _Up>
: > : > : _Iterator(const _Iterator<_Tp, _Dist, _Up*, _Up&>& __rhs);
: > : >
: > : > That's very unsafe. This will provide a conversion not only
: > : > from iterator to const_iterator but many other undesirable
: > : > _implicit_ conversions as well. For example,
: > : > vector<Derived>::iterator --> vector<Base>::iterator.
: >
: > : No, this is not a conversion from a const_iterator, it's just
: > : a copy of a const reference to an ordinary iterator.
: >
: > I think you are mistaken.
: Of course you are right.
: > BTW. Now that I look at this again, I see other problems with
: > this piece of code. First of all, technicaly, this is not just
: > a copy constructor, therefore the comment is incorrect. Second of all,
: > there is no matching [non-copy] assignment operator.
: In fact it's not a copy constructor at all; given this definition the
: compiler would still automatically generate a copy constructor. I agree
: that we don't want any promiscuously polymorphic copy constructors for
: vector and string, because the types they store cannot be used
: polymorphically.
: The assignment would also be compiler-generated.
Right. However, let me reiterate the point I wanted to make.
We need to define a [non-copy] constructor iterator->const_iterator.
Therefore we must not forget to define a [non-copy] assignment
iterator->const_iterator as well. If we don't, the [non-copy] construction
will not be equivalent to a construction followed by the [non-copy]
assignment. Although such a [non-copy] assignment might happen
automatically, due to implicit conversion of the right-hand side,
it will involve one more user-defined conversion, compared to the
[non-copy] construction. If, for example, the right-hand side was
already a result of an implicit user-defined conversion, the [non-copy]
assignment will not happen, because a compiler will not apply two
implicit user-defined conversions in a row. There are probably template
argument deduction issues as well.
[....]
: > Besides, if
: > we derive one from the other, and not explicitly ban the slicing,
: > we will introduce other bizarre _implicit_ conversions, like
: > iterator* --> const_iterator* (compare to T** --> const T**).
: >
: > In short, we'll never drive Plauger out of business if we
: > gonna repeat his mistakes :-)
: OK, agreed. I hadn't studied his mistakes beyond his having
: derived in the wrong direction (!). I would like to do some
: experiments with private derivation and some "using" exposures.
: The nice properties of built-in promotion are not to be given
: up lightly.
Ok. Let us know how it goes. In the meantime I'll implement
the straightforward one. I'll try tomorrow, on Tuesday.
This will give us one more implementation to compare things
against.
: > We could derived them from a common base, but this will
: > introduce a vtbl and we don't want that.
: Right, maybe. Anyway, for something as simple as a pointer
: wrapper I'm not sure implementation-inheritance would buy
: you anything anyway, besides built-in promotion.
I agree. I think the added benefits will be well worth the code
duplication. Let me reiterate them:
1. Plain, sane, easy-to-understand design. Since it's a free software
project, keeping it simple and easy-to-understand is a virtue
by itself, because it increases the pool of people capable and
willing to contribute.
2. The data member in the const_iterator will be a pointer to const.
3. No implicit template converting constructors or template assignment
operators.
4. iterators will be real classes with the names that a user expects.
Therefore sane and actualy useful error messages.
5. vector<char>::iterator and basic_string<char>::iterator will be
different and unrelated types.
Hopefully, with appropriate typedefs, the actual code will
actually be 90% identical. If properly documented, this
will almost completely mitigate the consequences of the
code duplication.
Oleg.
More information about the Libstdc++
mailing list