Topic: Modifying map keys
Author: jbuck@Synopsys.COM (Joe Buck)
Date: 1996/08/19 Raw View
kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763) writes:
>I should have looked before posting. This is what the current draft (or
>at least, the most recent I have) says, too. I think that it is
>probably the best solution, but it does mean that most of the time, you
>will have to explicitly designate the type when creating the pair,
>rather than simply using make_pair, and counting on type induction in
>the compiler.
make_pair is extremely simple, though. One could write make_map_pair:
template <class KeyType, class ValueType>
inline pair<KeyType, ValueType>
make_map_pair(const KeyType& x, const ValueType& y) {
return pair<const KeyType, ValueType>(x, y);
}
--
-- Joe Buck http://www.synopsys.com/pubs/research/people/jbuck.html
Work for something because it is good,
not just because it stands a chance to succeed. -- Vaclav Havel
[ 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 ]
Author: Matt Austern <austern@isolde.mti.sgi.com>
Date: 1996/08/19 Raw View
jbuck@Synopsys.COM (Joe Buck) writes:
> make_pair is extremely simple, though. One could write make_map_pair:
>
> template <class KeyType, class ValueType>
> inline pair<KeyType, ValueType>
> make_map_pair(const KeyType& x, const ValueType& y) {
> return pair<const KeyType, ValueType>(x, y);
> }
It's simpler than that, actually: make_pair works perfectly fine, at
least in principle. If x is of type KeyType and y is of type
ValueType, then make_pair will yield a pair<KeyType, ValueType>. Map
expects a pair<const KeyType, ValueType> instead, but that's OK:
there's a constructor that will convert pair<KeyType, ValueType> to
pair<const KeyType, ValueType>.
The constructor (see [lib.pairs]) is a member template: it constructs
a pair<T1, T2> from any pair<U1, U2> so long as U1 is convertible to
T1 and U2 is convertible to T2.
Compilers that permit member templates are still rare today, of
course, but they're becoming more common.
---
[ 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: jbuck@Synopsys.COM (Joe Buck)
Date: 1996/08/20 Raw View
I wrote:
>>for map<Key,Value,Compare>, the objects that iterators refer to are
>>of type <const Key,Value>. This means that it is possible to change
>>the value, but not the key, by doing, say, iterator->second = new_value
>>(while iterator->first = new_key would fail since it is an attempt
>>to modify a const object).
fjh@mundook.cs.mu.OZ.AU (Fergus Henderson) writes:
>What if the const object has some mutable fields?
Then these fields a map's key can be modified by calling a const member
function that modifies a mutable member. If this causes the map to break,
the Key class is misdesigned, since mutable is for implementing "logical
const". It would not cause a problem in the more common uses of mutable
(caching information).
--
-- Joe Buck http://www.synopsys.com/pubs/research/people/jbuck.html
Work for something because it is good,
not just because it stands a chance to succeed. -- Vaclav Havel
---
[ 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 ]
Author: lars.farm@nts.mh.se (Lars Farm)
Date: 1996/08/14 Raw View
J. Kanze <kanze@gabi-soft.fr> wrote:
> > If I modify a key in this manner, should I expect
> > that this should affect the order of the elements?
>
> This is an interesting point. The standard requires that the
> associative containers define two types: const_iterator and iterator,
> which are returned by the begin function for a const and a non-const
> container, respectively.
In the original Stepanov/Lee proposal map<Key,Value>::value_type was a
pair<const Key,Value>. The key has since alternated between const Key
and plain Key. It seems to me it must be a const Key. Then it doesn't
matter if it is iterator or const_iterator as far as the key is
concerned. They would refer to
iterator: pair<const Key,Value>
const_iterator: const pair<const Key,Value>
Affects only Value. Key always const. I don't know what the today
current draft says.
Similarly for set<T> that at least earlier made iterator the same as
const_iterator. Changing a value in a set would require erase(oldkey);
followed by insert(newkey). Seems reasonable to me.
--
Lars Farm, lars.farm@nts.mh.se
---
[ 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 ]
Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1996/08/15 Raw View
In article <199608142301323136653@dialup97-4-4.swipnet.se>
lars.farm@nts.mh.se (Lars Farm) writes:
|> J. Kanze <kanze@gabi-soft.fr> wrote:
|> > > If I modify a key in this manner, should I expect
|> > > that this should affect the order of the elements?
|> >
|> > This is an interesting point. The standard requires that the
|> > associative containers define two types: const_iterator and iterator,
|> > which are returned by the begin function for a const and a non-const
|> > container, respectively.
|> In the original Stepanov/Lee proposal map<Key,Value>::value_type was a
|> pair<const Key,Value>. The key has since alternated between const Key
|> and plain Key. It seems to me it must be a const Key. Then it doesn't
|> matter if it is iterator or const_iterator as far as the key is
|> concerned. They would refer to
|> iterator: pair<const Key,Value>
|> const_iterator: const pair<const Key,Value>
|> Affects only Value. Key always const. I don't know what the today
|> current draft says.
I should have looked before posting. This is what the current draft (or
at least, the most recent I have) says, too. I think that it is
probably the best solution, but it does mean that most of the time, you
will have to explicitly designate the type when creating the pair,
rather than simply using make_pair, and counting on type induction in
the compiler.
|> Similarly for set<T> that at least earlier made iterator the same as
|> const_iterator. Changing a value in a set would require erase(oldkey);
|> followed by insert(newkey). Seems reasonable to me.
Very reasonable, in fact.
--
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. 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 ]
Author: jbuck@Synopsys.COM (Joe Buck)
Date: 1996/08/17 Raw View
kanze@gabi-soft.fr (J. Kanze) writes:
>Some clarification as to what functions the iterator actually supports
>should be added to the standard. I would think that if i is an
>set<T>::iterator, *i would still return a const reference to the
>object. For map, the problem is more complex; I suspect that
>map<T>::iterator* should return some sort of helper object which would
>allow modifying the value field, but not the key. Frankly, however, I
>don't offhand see how to write such an object.
for map<Key,Value,Compare>, the objects that iterators refer to are
of type <const Key,Value>. This means that it is possible to change
the value, but not the key, by doing, say, iterator->second = new_value
(while iterator->first = new_key would fail since it is an attempt
to modify a const object).
--
-- Joe Buck http://www.synopsys.com/pubs/research/people/jbuck.html
Work for something because it is good,
not just because it stands a chance to succeed. -- Vaclav Havel
[ 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 ]
Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1996/08/17 Raw View
jbuck@Synopsys.COM (Joe Buck) writes:
>for map<Key,Value,Compare>, the objects that iterators refer to are
>of type <const Key,Value>. This means that it is possible to change
>the value, but not the key, by doing, say, iterator->second = new_value
>(while iterator->first = new_key would fail since it is an attempt
>to modify a const object).
What if the const object has some mutable fields?
--
Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3 | -- the last words of T. S. Garp.
---
[ 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: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1996/08/18 Raw View
lars.farm@nts.mh.se (Lars Farm) writes:
>Fergus Henderson <fjh@mundook.cs.mu.OZ.AU> wrote:
>
>> What if the const object has some mutable fields?
>
>Presumably they still compare the same otherwise 'mutable' is missused,
>since it is supposed to support logical constness.
Logical constness is a style issue --- the draft doesn't say anything
about logical constness. Indeed, the use of `mutable' in the example
in 7.1.5.1 paragraph 6 makes it clear that the example class, which
uses mutable in a way that does *not* preserve logical constness, is
nevertheless well-formed.
So the question remains, what if a const object with some mutable
fields is used as the key of a map, and the mutable fields are changed,
and the change effects the results of the comparison?
Yes, I know it is bad style, but does it result in undefined behaviour?
I think it is probably undefined by the catch-all rule: anything whose
behaviour is not explicitly defined somewhere in the draft is
implicitly defined to have undefined behaviour. But relying on the
catch-all rule makes it harder to be certain; it would be nice
if the draft had an explicit statement that covered this case.
--
Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3 | -- the last words of T. S. Garp.
---
[ 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: lars.farm@nts.mh.se (Lars Farm)
Date: 1996/08/18 Raw View
Fergus Henderson <fjh@mundook.cs.mu.OZ.AU> wrote:
> What if the const object has some mutable fields?
Presumably they still compare the same otherwise 'mutable' is missused,
since it is supposed to support logical constness.
--
Lars Farm, lars.farm@nts.mh.se
---
[ 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 ]
Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1996/08/14 Raw View
Tom Chatt <tom-chatt@vertel.com> writes:
> With STL associative containers, there are methods which
> allow one to obtain a non-const iterator to an element
> within the container (which is either the "key" only for
> a "set", or a pair<key_type, value_type> for "map").
>
> I don't see anything in the spec which prohibits the
> modification of this key through the iterator, yet
> this seems like it might be a bit problematic for
> the implementation. On an associative container with
> "unique keys", what is to prevent one from getting
> a non-const iterator to a contained element, and
> modifying the key so that it is no longer unique?
>
> If I modify a key in this manner, should I expect
> that this should affect the order of the elements?
This is an interesting point. The standard requires that the
associative containers define two types: const_iterator and iterator,
which are returned by the begin function for a const and a non-const
container, respectively.
I do not see anything in the standard that would require that
dereferencing the iterator would allow modifying the element; what is
required is that the functions which modify the container (erase,
insert, etc.) require a the iterator of the non-const type.
Some clarification as to what functions the iterator actually supports
should be added to the standard. I would think that if i is an
set<T>::iterator, *i would still return a const reference to the
object. For map, the problem is more complex; I suspect that
map<T>::iterator* should return some sort of helper object which would
allow modifying the value field, but not the key. Frankly, however, I
don't offhand see how to write such an object.
--
James Kanze (+33) 88 14 49 00 email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs Bourgeois, 67000 Strasbourg, France
Conseils en informatique industrielle --
-- Beratung in industrieller Datenverarbeitung
---
[ 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: Tom Chatt <tom-chatt@vertel.com>
Date: 1996/08/07 Raw View
With STL associative containers, there are methods which
allow one to obtain a non-const iterator to an element
within the container (which is either the "key" only for
a "set", or a pair<key_type, value_type> for "map").
I don't see anything in the spec which prohibits the
modification of this key through the iterator, yet
this seems like it might be a bit problematic for
the implementation. On an associative container with
"unique keys", what is to prevent one from getting
a non-const iterator to a contained element, and
modifying the key so that it is no longer unique?
If I modify a key in this manner, should I expect
that this should affect the order of the elements?
--
---------------------------------------------------------------
Tom Chatt tom-chatt@vertel.com
Vertel
550 N. Continental Blvd. Voice: 310/606-0800
El Segundo, CA 90245 Fax: 310/335-0186
[ 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 ]