Topic: Simple question ?
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/04/09 Raw View
Alex Martelli wrote:
>
> Mark.Huiskes@ZTW.WK.WAU.NL (Mark Huiskes) writes:
>
> >Hi, I have a very simple question, I think.
> >I'm using a set of objects and now I want to perform a (non-const)
> >memberfunction on each of the objects in the set, so I used the following
>
> An std::set<T>::iterator, dereferenced, returns a const T&; this is
> deemed necessary because, otherwise, a generic method called on such
> a dereferenced iterator might alter the item's proper order within
> the set, i.e. invalidate the set's whole structure. Therefore, what
> you want cannot be done without a const_cast<>, or some other trick
> such as, supposing that you don't actually care about the ordering
> of the elements in the set:
That makes perfect sense; now where does it say that in the standard?
---
[ 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 ]
Author: Mark.Huiskes@ZTW.WK.WAU.NL (Mark Huiskes)
Date: 1998/04/06 Raw View
Hi, I have a very simple question, I think.
I'm using a set of objects and now I want to perform a (non-const)
memberfunction on each of the objects in the set, so I used the following
lines of code:
TgStateSet::iterator gStateSetI=pState.gStateSet.begin();
for (gStateSetI=pState.gStateSet.begin();
gStateSetI!=pState.gStateSet.end();gStateSetI++) {
(*gStateSetI).Map(eState,Pars);
(*gStateSetI).iState.Map(eState,Pars);
}
I guess there's something wrong with this since my compiler says that the
dereferenced iterator (*gStateSetI) returns a constant object !! The
object pState enters the function in which I use this code through a non-
const reference (this is the function header: )
int Compute(TpState& pState, TeState& eState,
double* Pars, const int& tMin, const int& tMax) {
and nowhere in my original class definition do I mention anything about
it being constant. Could somebody help me with this ?
---
[ 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 ]
Author: martelli@cadlab.it (Alex Martelli)
Date: 1998/04/08 Raw View
Mark.Huiskes@ZTW.WK.WAU.NL (Mark Huiskes) writes:
>Hi, I have a very simple question, I think.
>I'm using a set of objects and now I want to perform a (non-const)
>memberfunction on each of the objects in the set, so I used the following
An std::set<T>::iterator, dereferenced, returns a const T&; this is
deemed necessary because, otherwise, a generic method called on such
a dereferenced iterator might alter the item's proper order within
the set, i.e. invalidate the set's whole structure. Therefore, what
you want cannot be done without a const_cast<>, or some other trick
such as, supposing that you don't actually care about the ordering
of the elements in the set:
template <typename T>
class wrapper {
const size_t prognum;
static size_t id;
mutable T t;
public:
wrapper(T t): t(t), prognum(++id) {}
wrapper(const wrapper& w): t(w.t), prognum(++id) {}
wrapper& operator=(const wrapper& w) {
t = w.t;
return *this;
}
operator T&() const { return t; }
T& unwrap() const { return t; }
bool operator<(const wrapper& w) const { return prognum<w.prognum; }
};
template <typename T> size_t wrapper<T>::id;
std::set<wrapper<whatever> > hset;
*Now* you can iterate through hset as in:
for(std::set<wrapper<whatever> >::iterator i = hset.begin();
i!=hset.end(); ++i)
i->unwrap().any_method();
secure in the knowledge that the any_method(), while possibly
modifying the "whatever" wrapped object, will not affect hset's
structure, since the less<wrapper<whatever> > only depends on
the wrapper objects' immutable prognum members.
This is only an outline, of course -- you'll want to tailor your
wrapper templates, or custom classes, to your actual needs (e.g.
a wrapper might hold a T by-reference rather than by-value, etc
etc). As long as the non-const methods you want to call on the
objects in the set will *definitely* not alter their comparison
orders, you might even have wrapper<T>::operator< delegate to
T::operator<. of course (under your sole responsibility... be
sure to comment such assumptions in detail, for maintainers'
sanity's sake!-).
The situation is more ticklish if you DO want to call, on objects
within a set, methods that MIGHT in fact change their sorting
order. If that is the case, then you may have to remove objects
from the set (to a list or whatever), iterate on the auxiliary
container, then rebuild the set from scratch. Designing a sorted
container which self-maintains its structure under arbitrary mods
to the contained elements is not trivial, and the Standard C++
Library sorted containers do not have this goal (which would make
operation substantially slower for all cases where such a goal is
not of interest).
Alex
--
____ Alex Martelli, Bologna, Italia -- email: alex@magenta.com
\SM/___ http://magenta.com/~alex
\/\bi/ You never know what is enough unless you know what
\/ is more than enough.
---
[ 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 ]