Topic: Constness of hint in insert method
Author: jpotter@falcon.lhup.edu (John Potter)
Date: 1999/06/25 Raw View
Dave Abrahams <abrahams@mediaone.net> wrote:
: Here's a simple and typical example problem which is currently very
: difficult to solve without the proposed change:
: Wrap a standard container C in a class W which allows clients to find and
: read (but not modify) a subrange of (C.begin(), C.end()]. The only
: modification clients are allowed to make to elements in this subrange is to
: erase them from C through the use of a member function of W.
I think I see your point.
template <class T> class W {
private :
std::list<T> data;
public :
list<T>::const_iterator begin () const { return data.begin(); }
list<T>::const_iterator end () const { return data.end(); }
list<T>::const_iterator erase (list<T>::const_iterator it) {
list<T>::iterator t(data.begin());
list<T>::const_iterator u(t);
advance(t, distance(u, it));
return data.erase(t);
}
};
Not only unpleasant but inefficient. If list<>::erase accepted a
const_iterator, that function would be
return data.erase(it);
Since the iterators are implementation defined, there is no way for
a user to convert a const_iterator to an iterator. OTOH, the
container implementator can do it easily.
John
---
[ 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: Dave Abrahams <abrahams@mediaone.net>
Date: 1999/06/18 Raw View
In article <Ddda3.24749$uk.406898@newscene.newscene.com> ,
jpotter@falcon.lhup.edu (John Potter) wrote:
> : Should this be a defect report?
Yes, it definitely should. In fact this problem is symptomatic of a problem
which appears throughout the STL container interfaces.
>: Does anyone know why the C++ spec is not written this way?
I suspect it was a conceptual problem on the part of the designers of the
STL. The generalized problem looks like this: all functions which modify
containers have been (erroneously) specified to accept only non-const
iterators in their parameter lists, whereas it is the constness of the
container object *itself* which is important.
In fact, all non-const iterator parameters to container member functions
should be changed to accept const_iterator parameters.
I tried to get this on the library issues list for the last meeting before
standardization, but at such a late date I had to pick my battles, and
standard library exception-safety seemed like a more pressing issue at the
time ;)
Here's a simple and typical example problem which is currently very
difficult to solve without the proposed change:
Wrap a standard container C in a class W which allows clients to find and
read (but not modify) a subrange of (C.begin(), C.end()]. The only
modification clients are allowed to make to elements in this subrange is to
erase them from C through the use of a member function of W.
-Dave
---
[ 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: jpotter@falcon.lhup.edu (John Potter)
Date: 1999/06/17 Raw View
"Ed Brey" <brey@afd.mke.etn.com> wrote:
: Does anyone know why the C++ spec is not written this way?
I guess not. <g>
Author: "Ed Brey" <brey@afd.mke.etn.com>
Date: 1999/06/11 Raw View
For associative containers, the hint parameter to the hinted insert method
is a non-const iterator. It seems to me that for associative containers, it
should be a const_iterator, since the insert method does not change what the
hint iterator is pointing to.
Additionally, it allows for safer programming. For instance, given a
multimap<int,char> for which there are many different ints, but only a few
different chars, the multimap might contain:
2,'A'
3,'A'
3,'B'
Suppose you wanted to insert 3,A only if it didn't already exist. You might
want to say:
pair<M::const_iterator, const_iterator> itit = m.equal_range(3);
M::const_iterator hint = itit.first;
for (;;++itit.first)
if (itit.first == itit.second)
m.insert(hint, make_pair(3, 'A'));
else if (itit.first->second == 'A')
break;
Using const_iterator is helpful for preventing mistakes. For example, it
would catch at compiler time the error that would exist if the last two
lines were:
else if (itit.first->second = 'A')
break;
Does anyone know why the C++ spec is not written this way? Should this be a
defect report?
---
[ 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 ]