Article View: comp.std.c++
Article #2573Re: Modifying STL containers via an iterator
From: James Kanze US/ESC 60/3/141 #407...
Date: Tue, 14 Nov 1995 20:38
Date: Tue, 14 Nov 1995 20:38
89 lines
3609 bytes
3609 bytes
In article <9511122227.AA22118@eniac.glue.ch> maeder@glue.CH (Thomas
Maeder) writes:
|> > Does the STL define the case where a container is modified while
|> > iterating through it?
|> Depends on the type of container.
|> > Example: (forgive me if the syntax isn't perfect...)
|> >
|> > class X x;
|> >
|> > for (X::iterator ix=x.begin(); ix != x.end(); ix++) {
|> > ix.erase();
There is no function erase in the iterator. This should be:
x.erase( ix ) ;
|> > }
|> >
|> I quote from the documentation to the free HP implementation (somebody
|> please correct if this doesn't match the draft):
|> list:
|> erase invalidates only the iterators and references to the erased
|> elements.
|> Your code works.
Since the iterator ix references the erased object, it becomes
invalid.
Whether the code works or not depends on what is meant by
`invalidates'. I think, in fact, that invalidates implies that *all*
further operations on the iterator are illegal. If this is the case,
then the comparison with x.end() after the x.erase( ix ) is illegal.
I seem to recall having heard somewhere that in the actual STL
implementation, the iterator to a vector is just a simple pointer. If
that is true, the above erase every other element, and if the initial
number of elements were odd, will result in an endless loop (with
erase being called with illegal pointer values).
One of the most useful idioms I've found with lists looks something
like the following (with my list class):
GB_DLListOf< T > list ;
for ( GB_DLListOf::Index i( list ) ; ! i.finished() ; ++ i )
{
if ( someCondition( list[ i ] ) )
list.remove( i ) ;
}
I hope the function names are clear enough without explination. My
"iterators" are called Index, and have index semantics instead of
pointer semantics. They are completely safe: removing the object
referenced by the iterator causes all further attempts to dereference
the iterator to fail, but does not otherwise invalidate the iterator,
nor change its position; incrementing it will cause it to point at the
object which followed the removed object, as one would naively expect.
To do the same with STL requires something like the following:
list< T > myList ;
list< T >::iterator i( myList.begin() ) ;
while ( i != myList.end() )
{
list< T >::iterator curr( i ++ ) ;
if ( someCondition( *curr ) )
myList.erase( curr ) ;
}
The incrementation *must* take place before the erase in order to work
correctly.
--
--
James Kanze Tel.: (+33) 88 14 49 00 email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils, études et réalisations en logiciel orienté objet --
-- A la recherche d'une activité dans une region francophone
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Technical Details
Message-ID:
<9511141139.AA01526@lts.sel.alcatel.de>Path:
arc1-ca.pugleaf.net!howland.reston.ans.net!agate!agate!MattReferences:
<47l8qe$9fk@bcarh8ab.bnr.ca> <9511122227.AA22118@eniac.glue.ch>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!howland.reston.ans.net!agate!agate!Matt From: James Kanze US/ESC 60/3/141 #40763 <kanze@lts.sel.alcatel.de> Newsgroups: comp.std.c++ Subject: Re: Modifying STL containers via an iterator Date: 14 Nov 1995 20:38:01 GMT Organization: <none> Approved: Matt@Austern Message-ID: <9511141139.AA01526@lts.sel.alcatel.de> References: <47l8qe$9fk@bcarh8ab.bnr.ca> <9511122227.AA22118@eniac.glue.ch> NNTP-Posting-Host: austern.hip.berkeley.edu