Modifying the value of key of a map.

Discussion in 'C++' started by Milind, May 30, 2006.

  1. Milind

    Milind Guest

    Hi,

    I have a map of the type:

    std::map<A, B> mymap_A;
    std::map<X, A> mymap_X;

    where A, B and X are user defined types (i.e. my own clases)

    At the beging of the program i do a insert on the maps. Later, at some
    point i come across a situation where the value of some member of A
    changes. e.g:

    class A {
    int a_member;
    };

    when i did an insert a_member was 2; now it is supposed to be 4.

    Problem:

    my first, and absolutely naive approach was:

    std::map<A,B>::iterator i = mymap.find(valueofkey);
    i->first = 4;

    But this is not allowed as i->first is read only.

    Now, the possible solution for this would be to either create a new
    pair (and necessarily copy everything in the value part... which is
    going to be very costly) and delete old and insert new pair.

    Am I missing something too obvious??

    Any pointers??

    Thnx.
    ~M
    Milind, May 30, 2006
    #1
    1. Advertising

  2. Milind

    Mark P Guest

    Milind wrote:
    > Hi,
    >
    > I have a map of the type:
    >
    > std::map<A, B> mymap_A;
    > std::map<X, A> mymap_X;
    >
    > where A, B and X are user defined types (i.e. my own clases)
    >
    > At the beging of the program i do a insert on the maps. Later, at some
    > point i come across a situation where the value of some member of A
    > changes. e.g:
    >
    > class A {
    > int a_member;
    > };
    >
    > when i did an insert a_member was 2; now it is supposed to be 4.
    >
    > Problem:
    >
    > my first, and absolutely naive approach was:
    >
    > std::map<A,B>::iterator i = mymap.find(valueofkey);
    > i->first = 4;
    >
    > But this is not allowed as i->first is read only.
    >
    > Now, the possible solution for this would be to either create a new
    > pair (and necessarily copy everything in the value part... which is
    > going to be very costly) and delete old and insert new pair.
    >
    > Am I missing something too obvious??
    >
    > Any pointers??
    >
    > Thnx.
    > ~M
    >


    The Key type of a map is necessarily a constant. If you want to
    "modify" it, the most direct approaches are to delete and re-insert as
    you suggested, or use a layer of indirection and let your key have a
    pointer to some other data which you can modify freely.

    Mark
    Mark P, May 30, 2006
    #2
    1. Advertising

  3. Milind

    shailesh Guest

    How about this?

    make the member a_member as mutable. And then modify it through the
    iterator.
    i->first.a_member = 4;

    Or may be through a const member function in class A? This would ensure
    that a_member doesn't need to be public.

    Just a hack off course.
    shailesh, May 30, 2006
    #3
  4. Milind

    Kai-Uwe Bux Guest

    shailesh wrote:

    > How about this?
    >
    > make the member a_member as mutable. And then modify it through the
    > iterator.
    > i->first.a_member = 4;


    Please quote. It is hard to know what a_member is without context.

    > Or may be through a const member function in class A? This would ensure
    > that a_member doesn't need to be public.
    >
    > Just a hack off course.


    And it may not cut it: we have not been given the details of the classes,
    but chances are that a_member takes place in the comparison of keys. If so,
    the modification may change the position of this map-entry relative to the
    other entries, the map is going to be messed up. In short: you are
    modifying a const object and what you earn is undefined behavior.


    Best

    Kai-Uwe Bux
    Kai-Uwe Bux, May 30, 2006
    #4
  5. Milind

    homsan toft Guest

    Milind wrote:
    > Hi,
    >
    > I have a map of the type:
    >
    > std::map<A, B> mymap_A;
    > std::map<X, A> mymap_X;
    >
    > where A, B and X are user defined types (i.e. my own clases)
    >
    > At the beging of the program i do a insert on the maps. Later, at some
    > point i come across a situation where the value of some member of A
    > changes. e.g:
    >
    > class A {
    > int a_member;
    > };
    >
    > when i did an insert a_member was 2; now it is supposed to be 4.
    >
    > Problem:
    >
    > my first, and absolutely naive approach was:
    >
    > std::map<A,B>::iterator i = mymap.find(valueofkey);
    > i->first = 4;
    >
    > But this is not allowed as i->first is read only.
    >
    > Now, the possible solution for this would be to either create a new
    > pair (and necessarily copy everything in the value part... which is
    > going to be very costly) and delete old and insert new pair.
    >
    > Am I missing something too obvious??
    >


    It's hard to tell without looking into your intentions, and perhaps at classes B and X.
    Maybe you mixed up the Key and Value parts, or you want something other than a map<A,B>, or...

    The basic idea of a map<Key,Value> is that you do (fast) lookup by key,
    but you can edit the data freely.
    Like
    mymap[player.id()].lives--;
    or
    mymapiter i = mymap.find(player.id()); // mymapiter is supposed to be a (badly named) typedef
    if (i != mymap.end()) // if you use find, you must test, otherwise you crash on dereference
    i->lives--;

    player.id() is the key here. The data is a struct with an int-like member 'lives'.
    If you use any other key, you should be looking at other data, ie the data of another player.
    And obviously, the id shouldn't change (if it does "id" is probably a bad name for it).
    This is what std::maps are supposed to be good for.

    If you want to look up by data, eg to find all players with zero lives,
    you need something different (perhaps a bidirectional map - is this why you
    have both map<A,B> and map<X,A> ? - no way for us to know...)

    HTH
    homsan
    homsan toft, May 30, 2006
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Patrick Guio
    Replies:
    6
    Views:
    3,195
    chris
    Oct 20, 2004
  2. Rui Maciel
    Replies:
    2
    Views:
    3,024
    AndrewDover
    Dec 1, 2009
  3. Trans
    Replies:
    8
    Views:
    152
    Trans
    Apr 13, 2005
  4. Une bévue
    Replies:
    5
    Views:
    148
    Une bévue
    Aug 10, 2006
  5. Antonio Quinonez
    Replies:
    2
    Views:
    167
    Antonio Quinonez
    Aug 14, 2003
Loading...

Share This Page