How to make insert-and-overwrite into a map - c++

This is a discussion on How to make insert-and-overwrite into a map - c++ ; Hi. Since std::map::insert doesn't overwrite the mapped value of an already-existing key, I wonder how to accomplish an overwriting insert. Using operator[] is not a good idea because it enforces the mapped value to be default constructible. Checking the boolean ...

+ Reply to Thread
Results 1 to 6 of 6

How to make insert-and-overwrite into a map

  1. Default How to make insert-and-overwrite into a map

    Hi.
    Since std::map::insert doesn't overwrite the mapped value of an
    already-existing key, I wonder how to accomplish an overwriting
    insert. Using operator[] is not a good idea because it enforces the
    mapped value to be default constructible. Checking the boolean value
    returned by insert() and if necessary, calling find(), and assign to
    the found value, is also not a good idea because it means searching
    the map happens twice - both by insert() and find() - which is
    inefficient.

    Is there another way, or was it just forgotten by the map interface
    designers?
    Yuval


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


  2. Default Re: How to make insert-and-overwrite into a map

    On 1 oct, 10:49, yuval.ro...@gmail.com wrote:
    > Hi.
    > Since std::map::insert doesn't overwrite the mapped value of an
    > already-existing key, I wonder how to accomplish an overwriting
    > insert. Using operator[] is not a good idea because it enforces the
    > mapped value to be default constructible. Checking the boolean value
    > returned by insert() and if necessary, calling find(), and assign to
    > the found value, is also not a good idea because it means searching
    > the map happens twice - both by insert() and find() - which is
    > inefficient.


    We recently stumbled on the same question. Here is what we did:

    template<typename MapT>
    typename MapT::iterator
    InsertOrUpdate(MapT& Map, const typename MapT::value_type& Value)
    {
    std:air<typename MapT::iterator, bool> result =
    Map.insert(Value);
    if (!result.second) {
    result.first->second = Value.second;
    }
    return result.first;
    }


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


  3. Default Re: How to make insert-and-overwrite into a map

    On Oct 1, 7:49 pm, yuval.ro...@gmail.com wrote:
    > Checking the boolean value
    > returned by insert() and if necessary, calling find(), and assign to
    > the found value, is also not a good idea because it means searching
    > the map happens twice - both by insert() and find() - which is
    > inefficient.
    >
    > Is there another way,...


    Insert returns pair<iterator, bool>. If bool value is false - iterator
    to the existing object is returned which you can directly use for
    overwrite (assignment) without doing a redundant find. If successful,
    returns the iterator to the newly added element.


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


  4. Default Re: How to make insert-and-overwrite into a map

    On 1 Okt., 16:49, yuval.ro...@gmail.com wrote:
    > Since std::map::insert doesn't overwrite the mapped value of an
    > already-existing key, I wonder how to accomplish an overwriting
    > insert. Using operator[] is not a good idea because it enforces the
    > mapped value to be default constructible. Checking the boolean value
    > returned by insert() and if necessary, calling find(), and assign to
    > the found value, is also not a good idea because it means searching
    > the map happens twice - both by insert() and find() - which is
    > inefficient.
    >
    > Is there another way, or was it just forgotten by the map interface
    > designers?


    It has not been forgotten. If you take a look at insert (with one
    argument), you will realize that it also returns std:air<iterator,
    bool>,
    which points to the solution you are looking for:

    #include <utility>

    // Returns whether the key already existed or not
    template <typename MapType>
    bool put(MapType& m, const typename MapType::value_type& v) {
    std:air<typename MapType::iterator, bool> result =
    m.insert(v);
    if (!result.second) {
    result.first->second = v.second;
    }
    return result.second;
    }

    Greetings from Bremen,

    Daniel Krügler



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


  5. Default Re: How to make insert-and-overwrite into a map

    On Oct 1, 10:49 am, yuval.ro...@gmail.com wrote:
    > Hi.
    > Since std::map::insert doesn't overwrite the mapped value of an
    > already-existing key, I wonder how to accomplish an overwriting
    > insert. [...]
    > Is there another way, or was it just forgotten by the map interface
    > designers?


    I think the most efficient way to accomplish this is to use map's
    lower_bound member to find an iterator to the element (or an iterator
    to where it the element should be.) If it returns an iterator to the
    element, overwrite its value. If it returns an end iterator or an
    iterator to an element other than the one you want, you can then
    create a new object (using any means you desire) and call insert()
    using the iterator as the location hint (thereby avoiding a second
    lookup in the tree.)

    Chris


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


  6. Default Re: How to make insert-and-overwrite into a map

    In article <1191237032.879861.126100@w3g2000hsg.googlegroups.com>,
    <yuval.ronen@gmail.com> wrote:

    > Hi.
    > Since std::map::insert doesn't overwrite the mapped value of an
    > already-existing key, I wonder how to accomplish an overwriting
    > insert. Using operator[] is not a good idea because it enforces the
    > mapped value to be default constructible. Checking the boolean value
    > returned by insert() and if necessary, calling find(), and assign to
    > the found value, is also not a good idea because it means searching
    > the map happens twice - both by insert() and find() - which is
    > inefficient.
    >
    > Is there another way, or was it just forgotten by the map interface
    > designers?

    there is
    std:air<iterator,bool> insert(value_type const &);

    returns an pair the iterator points to the item with the key
    that is in the map, and the bool is true if item was inserted,
    so something like:

    template <class Map>
    void always_insert(Map &m,typename Map::value_type const &v)
    {
    std:air<typename Map::iterator,bool> res = m.insert(v);
    if(!res.second) // key was already in map change it.
    *res.first = v;
    }

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


+ Reply to Thread

Similar Threads

  1. How to overwrite value in id?
    By Application Development in forum Javascript
    Replies: 4
    Last Post: 09-26-2007, 11:19 PM
  2. How to overwrite the interop in GAC
    By Application Development in forum DOTNET
    Replies: 1
    Last Post: 08-29-2007, 12:31 PM
  3. textbox Overwrite/insert mode
    By Application Development in forum Javascript
    Replies: 0
    Last Post: 09-05-2006, 03:38 AM
  4. PC-Pine, copy/paste, ctrl-Insert / shift-Insert
    By Application Development in forum Pine
    Replies: 5
    Last Post: 05-25-2005, 07:26 PM
  5. Insert/overwrite key state
    By Application Development in forum CSharp
    Replies: 0
    Last Post: 05-09-2005, 10:16 AM