From -8584979814718490454
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: f78e5,7eaa8faac8da5016
X-Google-Attributes: gidf78e5,public
From: "Darin Adler" <darin@bentspoon.com>
Subject: Re: Defect Report: member == in container iterators considered harmful
Date: 1999/08/18
Message-ID: <7pcr52$2mh8@enews2.newsguy.com>#1/1
X-Deja-AN: 514097025
X-NNTP-Posting-Host: news.newsdawg.com
Content-Transfer-Encoding: 7bit
Approved: stephen.clamage@sun.com (comp.std.c++)
References: <7p4nj8$n3u@enews4.newsguy.com> <37B98C2E.E3A1EA71@acm.org>
X-UID: 0000000001
X-Status: $$$T
Content-Type: text/plain; charset="US-ASCII"
Organization: http://extra.newsguy.com
Mime-Version: 1.0
Newsgroups: comp.std.c++
Originator: clamage@taumet


Pete Becker <petebecker@acm.org> wrote:

> Agreed. But the begin and end iterators that you get from a container
> are of the same type, and they work just fine for the standard STL
> idioms. Why do you need to do this? What coding practices does it
> support?

This originally came to my attention because of a question another C++ user
asked me about why his code wasn't compiling. The code was otherwise quite
good and didn't go beyond the standard in other ways. I realized that some
compilers might accept the == comparison and others wouldn't. It seemed
unnecessary to leave this unspecified in the standard, since one approach
was clearly superior. As far as I can tell, in every other case of a class
defined in the standard library, the standard mandates non-member functions
for this kind of binary operator.

I encountered a similar problem when rolling out a checked implementation of
vector that I was experimenting with. When the vector iterators were defined
as instances of a class rather than as pointers, this == comparison problem
showed up in some user code. I fixed the problem by making operator == be a
friend function instead of a member function, but it revealed that there was
code lurking that didn't comply with the standard. I had a hard time
explaining why reversing the order of the operands to == would make the code
"correct" to my colleagues.

I don't know all the situations where this could come up, but a common one
is where you have a const_iterator and a container and want to compare it
against the beginning or end iterator of a container. (I agree that with the
typical STL idiom you would have the begin and end iterators, not the
container.) If you happen to have a non-const reference to the container,
the comparison only works in one direction. The opposite occurs if you have
a non-const iterator and a const reference to the container.

Other examples come up when you store a const_iterator, then need to compare
it against a parameter that's an iterator, or when you store an iterator and
need to compare it against a parameter that's a const_iterator. This doesn't
come up often with deque<>, since iterators are invalidated by so many
operations, but it does come up with list<>.

The real issue for me is not the need to write code like this, but the fact
that code like this will work on some implementations, but is not required
to work on other standard-conforming implementations. I think it's nice to
minimize unspecified cases like this in the standard if possible, unless
there's significant flexibility or clarity gained by leaving it unspecified.

For example, I'm glad that the standard does not allow operator+(const
string&, const string&) to be implemented as a member function of class
string, because it would otherwise be too easy to accidentally write code
that works on some implementations but not others.

Much of my work involves modifying and maintaining programs that other
people write. Thus, the issue affects me even if I never plan to write code
that uses iterators in this way. I'm often the first programmer to expose
existing code to a new compiler.

I'd like to counter with another question:

With the standard STL idioms, there is no reason to convert between
iterators and const_iterators. If you are operating on a modifiable
container, you use iterators. If it's a const reference to the container,
then you use const_iterators. Why, then, does the standard require a
conversion from iterator to const_iterator for the container classes?

    -- Darin


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]




