Topic: STL set iterators, const or non-const?
Author: "Bob Sanford" <Bob.Sanford@Compaq.com>
Date: 1997/07/11 Raw View
Does anyone know why both "iterator" and "const_iterator" are defined the
same in the "set" container class of the STL? They are both const. This is
a bit of a problem if you need to modify your objects while iterating. As a
work-around, I modified the set class template in set.h as shown here:
from:
typedef typename rep_type::const_iterator iterator;
typedef typename rep_type::const_iterator const_iterator;
to:
typedef typename rep_type::iterator iterator;
typedef typename rep_type::const_iterator const_iterator;
Why wasn't it done this way to begin with? I'm using BC++ 5.02, but I found
the same problem in VisualC++ 5.0 and in Silicon Graphics' STL. I suspect
there's a reson they did this. Perhaps while iterating, they don't want us
to change an object's attributes that could affect the compare functions
used for sorting. This would corrupt the red-black tree that the set
container is based on. But I still want to call non-const functions for my
objects that may modify other attributes. Why have two types of iterators,
if they're really the same? I don't want to have to use "const_cast" that
often. I try to avoid that.
Thanks,
Bob Sanford
<Bob.Sanford@Compaq.com>
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: steagall@deltalogic.com (Bob Steagall)
Date: 1997/07/11 Raw View
"Bob Sanford" <Bob.Sanford@Compaq.com> wrote:
>Does anyone know why both "iterator" and "const_iterator" are defined the
>same in the "set" container class of the STL? They are both const. This is
>a bit of a problem if you need to modify your objects while iterating. As a
>work-around, I modified the set class template in set.h as shown here:
>from:
> typedef typename rep_type::const_iterator iterator;
> typedef typename rep_type::const_iterator const_iterator;
>to:
> typedef typename rep_type::iterator iterator;
> typedef typename rep_type::const_iterator const_iterator;
You could be treading very dangerous ground here.
>Why wasn't it done this way to begin with? I'm using BC++ 5.02, but I found
>the same problem in VisualC++ 5.0 and in Silicon Graphics' STL. I suspect
>there's a reson they did this. Perhaps while iterating, they don't want us
>to change an object's attributes that could affect the compare functions
>used for sorting. This would corrupt the red-black tree that the set
>container is based on.
This is exactly the reason why iterators are equivalent to non-const
iterators in ordered sets and ordered multisets.
>... But I still want to call non-const functions for my
>objects that may modify other attributes. Why have two types of iterators,
>if they're really the same?
The standard requires that the nested type aliases 'iterator' and
'const_iterator' be defined for each container type.
>... I don't want to have to use "const_cast" that
>often. I try to avoid that.
Suppose you have some class that you are creating, with the intention of
placing instances of that class into an ordered set. One approach, very
inelegant but functional, would be to make those non-const member
functions you want to invoke const, and make the member objects they
modify mutable. Of course, you would have to guarantee that those
member objects and the corresponding 'true' selectors that define the
ordering of the class type do not get modified when any of the 'phony'
selectors get called. This eliminates the const_cast, but is very ugly
nonetheless.
Another quick and slightly less dirty solution would be to create a
group of functions to perform the modification. They would remove the
element from the set, perform the required non-const operation(s), and
then insert the newly-modified key value back into the set.
--Bob
====================================================================
Bob Steagall steagall@deltalogic.com
DeltaLogic, Inc. http://www.deltalogic.com
1537 Kew Road Voice (216) 321-8200
Cleveland Hts, OH 44118-1204 Fax (216) 321-6976
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: Alexandre Oliva <oliva@dcc.unicamp.br>
Date: 1997/07/12 Raw View
Bob Sanford writes:
> Does anyone know why both "iterator" and "const_iterator" are
> defined the same in the "set" container class of the STL? They are
> both const. This is a bit of a problem if you need to modify your
> objects while iterating.
You must not alter objects in a set. Since a set is an ordered
container and the order depends on a key that is the object itself,
changing the object might change the key, but the object would not be
reinserted in the right position. Thus, you'd be breaking the set by
doing that. Of course, if you *know* what you're doing, you can
always const_cast<T&>(*the_iterator);
> As a work-around, I modified the set class template in set.h as
> shown here:
Undo your changes, you're making your code unportable. If you really
need that, you may subclass std::set and define your own operations
that provide the iterators type you prefer.
--
Alexandre Oliva
mailto:oliva@dcc.unicamp.br mailto:aoliva@acm.org
Universidade Estadual de Campinas, SP, Brasil
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]