This is the mail archive of the libstdc++@sourceware.cygnus.com mailing list for the libstdc++ project. See the libstdc++ home page for more information.


[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index] [Subject Index] [Author Index] [Thread Index]

Re: Iterator class for vector and basic_string



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.