std::map insert element issue

Z

zs0723

I need to changed the value of a key in std::map, i have written the
following code :


#include <map>
#include <iostream>
#include <string>
using namespace std;

int main()
{
typedef map<string,string> TABLE;
typedef TABLE::iterator ITERATOR;
TABLE table;

table.insert(TABLE::value_type("zs","victor"));

if(table.insert(TABLE::value_typezs","xiao v")).second) // this
will failed , i can't overwirte the exist key's value
cout<<"insert success\n";
else
cout<<"insert failied\n";

// but use like array 's [] , it's ok
// table["zs"]="victor";
// table["zs"]="xiao v";
for(ITERATOR itr=table.begin();itr != table.end() ; ++itr)
{
cout<<itr->first <<":"<<itr->second;
cout<<endl;
}

cout<<std::endl;
}

My question is :
Why insert method can't overwrite the value of the existing key.
Thanks
 
Y

yifanernei

if the key is exists, insert func will fail.

The operator [] return a reference of the value
like this:
T& operator [](const key_type & k);
 
R

Raquib

if the key is exists, insert func will fail.

The operator [] return a reference of the value
like this:
T& operator [](const key_type & k);

hey dear,
I am little bit confused here. You want to change the key itself or
want to change the value of the corresponding key.
if the case you want to change the value assigned to a particular key
inside the map, then your insert will return a pair like
std::pair<bool, iterator of the map>, if insertion succeeds then bool
value will be true other wise bool will be false. check for the bool
value if it is false then from iterator change the value.
thanks
raquib
 
J

James Kanze

I need to changed the value of a key in std::map,

You can't change the value of a key without incurring undefined
behavior. The key determines where the element is stored in the
map; changing the key would imply changing where the element is
stored.

The only way to do this is to remove the element, modify the
key, and reinsert it.
i have written the following code :
#include <map>
#include <iostream>
#include <string>
using namespace std;
int main()
{
typedef map<string,string> TABLE;
typedef TABLE::iterator ITERATOR;
TABLE table;

if(table.insert(TABLE::value_type(s","xiao v")).second) // this
will failed , i can't overwirte the exist key's value
cout<<"insert success\n";
else
cout<<"insert failied\n";

This looks more like you're trying to change the value of the
mapped object, and not the key. Except that you're requesting
an explicit insertion of a new object.
// but use like array 's [] , it's ok
// table["zs"]="victor";
// table["zs"]="xiao v";

Of course. Are you surprised that two functions with different
names (operator[] and insert) have different semantics?
for(ITERATOR itr=table.begin();itr != table.end() ; ++itr)
{
cout<<itr->first <<":"<<itr->second;
cout<<endl;
}

My question is :
Why insert method can't overwrite the value of the existing
key.

Because that's the way it is specified. If it were specified to
change the mapping of an existing entry, of course, "insert"
would be a very, very poor name.
 
I

i.albert.cheng

I need to changed the value of a key in std::map, i have written the
following code :

#include <map>
#include <iostream>
#include <string>
using namespace std;

int main()
{
   typedef map<string,string> TABLE;
   typedef TABLE::iterator ITERATOR;
   TABLE table;

   table.insert(TABLE::value_type("zs","victor"));

   if(table.insert(TABLE::value_typezs","xiao v")).second) // this
will failed , i can't overwirte the exist key's value
      cout<<"insert success\n";
   else
      cout<<"insert failied\n";

// but use like array 's [] , it's ok
//  table["zs"]="victor";
//  table["zs"]="xiao v";
   for(ITERATOR itr=table.begin();itr != table.end() ; ++itr)
   {
         cout<<itr->first <<":"<<itr->second;
         cout<<endl;
   }

   cout<<std::endl;

}

My question is :
   Why  insert method can't overwrite the value of the existing key..
Thanks

Basically there two ways of inserting item in terms of std::map.

1>
The first and more traditional way is call insert() which applies to
all unique associative containers , e.g std::set , std::map.
When doing a a.insert(t),inserts t into a if and only if a does not
already contain an element whose key is the same as the key of t.

2>
The second way is unique for std::map , called operator[], which is
only for convenience, not necessary needed.
It merely equals to (*(a.insert(t, data_type()).first)).second .

Gob00st
 
Z

zs0723

Christian Hackl ha scritto:
zs0723 ha scritto:
I need to changed the value of a key in std::map, [...]
You can't. All you can do is delete the existing element and insert a
new one.

Uh-oh, I guess I misunderstood you completely. Thought you wanted to
change the key itself, rather than the value corresponding to the key.
Sorry for the confusion! :)


Sorry for my English,i want to overwrite the second element of the
pair<key,value>.
if this pair is in the map .
 
Z

zs0723

I need to changed the value of a key in std::map,

You can't change the value of a key without incurring undefined
behavior.  The key determines where the element is stored in the
map; changing the key would imply changing where the element is
stored.

The only way to do this is to remove the element, modify the
key, and reinsert it.


i have written the following code :
#include <map>
#include <iostream>
#include <string>
using namespace std;
int main()
{
   typedef map<string,string> TABLE;
   typedef TABLE::iterator ITERATOR;
   TABLE table;
   table.insert(TABLE::value_type("zs","victor"));
   if(table.insert(TABLE::value_type(s","xiao v")).second) // this
will failed , i can't overwirte the exist key's value
      cout<<"insert success\n";
   else
      cout<<"insert failied\n";

This looks more like you're trying to change the value of the
mapped object, and not the key.  Except that you're requesting
an explicit insertion of a new object.
// but use like array 's [] , it's ok
//  table["zs"]="victor";
//  table["zs"]="xiao v";

Of course.  Are you surprised that two functions with different
names (operator[] and insert) have different semantics?
   for(ITERATOR itr=table.begin();itr != table.end() ; ++itr)
   {
         cout<<itr->first <<":"<<itr->second;
         cout<<endl;
   }
   cout<<std::endl;
}
My question is :
Why  insert method can't overwrite the value of the existing
key.

Because that's the way it is specified.  If it were specified to
change the mapping of an existing entry, of course, "insert"
would be a very, very poor name.

Thanks a lot , but i have another question when i use insert method
to put a pair<key,value> ,this operation will be failed ,if the key
is already existing in the map.
So if we use the insert method of map ,we need to check the return
value of the method ?
 
J

Juha Nieminen

zs0723 said:
My question is :
Why insert method can't overwrite the value of the existing key.

Because std::map has been defined so that if you try to insert a key
which already exists, it won't do anything.

If you want to change the data attached to that key, then you'll have
to perform a find() and use the returned iterator to change the data. Or
you could use the handier: table[key] = value;

There might be some situations where two (key) elements compare equal
but are nevertheless not the same, and you would want to replace an
existing key with a new one (which, as said, compares equal to it, but
is not the same key). While this is usually a rather bad design
(differing objects comparing equal is rather dubious practice), you can
still do it: Simply remove the existing key first and then insert the
new one. However, this is probably not what you are doing, as your key
is simply a std::string.
 
J

James Kanze

On Feb 5, 6:40 pm, James Kanze <[email protected]> wrote:

[...]
So if we use the insert method of map ,we need to check the
return value of the method ?

Maybe. Usually, in fact.

Basically, there are three ways to "access" elements in the map:

insert: If you want to create a new element.
find: If you want to access an existing element.
operator[]: If you want to access an existing element, and
create a new one if it doesn't exist.

There is one problem with operator[], however, even when it does
what you want: it only works if the mapped_type supports default
construction. A lot of types don't. In those cases, you need
to use find, followed by an insert if find fails. (And of
course then, you don't have to check the return status of
insert.)
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,736
Latest member
AdolphBig6

Latest Threads

Top