Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

map::value_type without a const key

41 views
Skip to first unread message

ShaunJ

unread,
Nov 10, 2009, 3:27:04 AM11/10/09
to
map::value_type is defined as
pair<const Key,T>

I would find a typedef whose key is not const very useful. Does such a
typedef exist as a standard, or will it have to be
pair<mymap::key_type, mymap::mapped_type>

Cheers,
Shaun

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Neil Butterworth

unread,
Nov 10, 2009, 7:59:43 AM11/10/09
to
ShaunJ wrote:
> map::value_type is defined as
> pair<const Key,T>
>
> I would find a typedef whose key is not const very useful. Does such a
> typedef exist as a standard, or will it have to be
> pair<mymap::key_type, mymap::mapped_type>
>

A new typedef wouldn't do you much good. The reason the key is const is
because const keys are intrinsic to the correct internal workings of
std::map. If you did change the key, the map would (depending on exactly
what the new value was) stop working.

Neil Butterworth

tohava

unread,
Nov 10, 2009, 8:04:40 AM11/10/09
to
On Nov 10, 10:27 am, ShaunJ <sjack...@gmail.com> wrote:
> map::value_type is defined as
> pair<const Key,T>
>
> I would find a typedef whose key is not const very useful. Does such a
> typedef exist as a standard, or will it have to be
> pair<mymap::key_type, mymap::mapped_type>

The way that the pair is stored on the map depends on the value of the
key. There would need to be some mechanism that allows it to move
within the map for you to change the key. While this can be
implemented by properties (which do not exist as language feature in C+
+ but can be implemented via inner class + operator overload), this
would complicate the design of the container.

ShaunJ

unread,
Nov 10, 2009, 4:39:33 PM11/10/09
to
On Nov 10, 4:59 am, Neil Butterworth <nbutterworth1...@gmail.com>
wrote:

> ShaunJ wrote:
> > map::value_type is defined as
> > pair<const Key,T>
>
> > I would find a typedef whose key is not const very useful. Does such a
> > typedef exist as a standard, or will it have to be
> > pair<mymap::key_type, mymap::mapped_type>
>
> A new typedef wouldn't do you much good. The reason the key is const is
> because const keys are intrinsic to the correct internal workings of
> std::map. If you did change the key, the map would (depending on exactly
> what the new value was) stop working.

Sorry, I didn't explain myself fully. I'm looking for some syntatic
sugar to be able to modify the key of the pair before I insert it into
the map.

mymap::value_type v(foo, bar);
if (flag)
v.first = mogrify(v.first);
mymap.insert(v);

Cheers,
Shaun

shahav

unread,
Nov 10, 2009, 4:41:22 PM11/10/09
to
On Nov 10, 10:27 am, ShaunJ <sjack...@gmail.com> wrote:
> map::value_type is defined as
> pair<const Key,T>
>
> I would find a typedef whose key is not const very useful. Does such a
> typedef exist as a standard, or will it have to be
> pair<mymap::key_type, mymap::mapped_type>
>
> Cheers,
> Shaun

What you are asking for violate the very basic of container of
entities which are 'sorted'. If your really wish to modify the key and
not some other portion of the data, then you will have to 'erase' and
re-'insert' the object.
If your key can be chopped to two portion - then you better use map,
in which the key is const and the value is modifiable.
A different way of implementation could be using a stl::set with a
different comperator then the default.
but usually you will endup with syntatic sugar for using 'set' instead
of map.
Note - not just the std::map require the key to be const but also all
impl of hash based containers.

bottom line - you will have to erase/insert if wish to stick to
destructive key.
Rabin

Neil Butterworth

unread,
Nov 11, 2009, 12:14:16 AM11/11/09
to
ShaunJ wrote:

> Sorry, I didn't explain myself fully. I'm looking for some syntatic
> sugar to be able to modify the key of the pair before I insert it into
> the map.
>
> mymap::value_type v(foo, bar);
> if (flag)
> v.first = mogrify(v.first);
> mymap.insert(v);

How about this (untested code):

mymap::value_type v(foo, bar);
mymap.insert(
flag
? mymap::value_type( mogrify(v.first), v.bar )
: v
);

Neil Butterworth

shahav

unread,
Nov 11, 2009, 2:51:22 PM11/11/09
to
On Nov 11, 7:14 am, Neil Butterworth <nbutterworth1...@gmail.com>
wrote:

> ShaunJ wrote:
> > Sorry, I didn't explain myself fully. I'm looking for some syntatic
> > sugar to be able to modify the key of the pair before I insert it into
> > the map.
>
In order to clarify when exactly you wish to modify the key, you may
consider having two types myKey and mogrifyed_key.

still remember that what you ask does not make sense, assuming
modifing the key in insertion only -

MyMap mapInst;
Key key;
mapInst.insert(make_pair(key,val));
mapInst.find(key)->...// core dump since find should search for
mogrified(key)?

I don't wan to think about [] which involves find/insert...
Still, you may consider using a comperant which mimic the mogrifiy,
but keep the keys as originally stated.
Rabin

tohava

unread,
Nov 11, 2009, 2:51:49 PM11/11/09
to
> mymap::value_type v(foo, bar);
> if (flag)
> v.first = mogrify(v.first);
> mymap.insert(v);

What about removing the old pair after you inserted the new one?

Goran

unread,
Nov 11, 2009, 2:50:55 PM11/11/09
to
On Nov 10, 10:39 pm, ShaunJ <sjack...@gmail.com> wrote:
> Sorry, I didn't explain myself fully. I'm looking for some syntatic
> sugar to be able to modify the key of the pair before I insert it into
> the map.
>
> mymap::value_type v(foo, bar);
> if (flag)
> v.first = mogrify(v.first);
> mymap.insert(v);

So don't put a key into value_type before knowing it's value? Are you
doing it this way because key so expensive to copy?

Alternatively, you could try using mutable keyword: if mogrify changes
only parts of the key that do not participate in map ordering, there
is no problem (aolthough it does not smell that good to me). As said,
you are going against the tide: key is const because otherwise,
conceptually, map container can't guarantee ordering.

Goran.

rado

unread,
Nov 11, 2009, 8:04:35 PM11/11/09
to
On Nov 10, 12:27 am, ShaunJ <sjack...@gmail.com> wrote:
> map::value_type is defined as
> pair<const Key,T>
>
> I would find a typedef whose key is not const very useful. Does such a
> typedef exist as a standard, or will it have to be
> pair<mymap::key_type, mymap::mapped_type>
>
> Cheers,
> Shaun

Use const_cast (on references).
Don't let your modification change the order!!!

Seungbeom Kim

unread,
Nov 11, 2009, 8:21:08 PM11/11/09
to
ShaunJ wrote:
> On Nov 10, 4:59 am, Neil Butterworth <nbutterworth1...@gmail.com>
> wrote:
>> ShaunJ wrote:
>>> map::value_type is defined as
>>> pair<const Key,T>
>>> I would find a typedef whose key is not const very useful. Does such a
>>> typedef exist as a standard, or will it have to be
>>> pair<mymap::key_type, mymap::mapped_type>
>> A new typedef wouldn't do you much good. The reason the key is const is
>> because const keys are intrinsic to the correct internal workings of
>> std::map. If you did change the key, the map would (depending on exactly
>> what the new value was) stop working.
>
> Sorry, I didn't explain myself fully. I'm looking for some syntatic
> sugar to be able to modify the key of the pair before I insert it into
> the map.
>
> mymap::value_type v(foo, bar);
> if (flag)
> v.first = mogrify(v.first);
> mymap.insert(v);

How about this:

mymap::value_type v(flag ? mogrify(foo) : foo, bar);
mymap.insert(v);

or even

mymap.insert(mymap::value_type(flag ? mogrify(foo) : foo, bar));

(By the way, you cannot use the same name in front of ::value_type
and .insert.)

--
Seungbeom Kim

0 new messages