Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ STL map - conditional insert

Tags:

c++

map

stl

I'm looking for an efficient way to do a conditional insert. Ideally, I'd like a template function that would work on any map. I want something like this:

std::map<int, std::string> MyMap;
if(MyMap.ConditionalInsert(3, "Hello"))
{ // there was no element 3, one has been added with value "Hello"
}
else
{ // there was already an element 3 in the map, it's unchanged
}

I can't easily use operator[] because there's no easy way to tell if it created an element or not. I can use count for the test, but then I have to search the map twice if we do an insert. I guess something with find would be best, but it always seems to come out warty and awkward.

Is there a really good way to do this?

like image 968
David Schwartz Avatar asked Dec 21 '22 04:12

David Schwartz


2 Answers

What problem do you see with this:

auto ret = MyMap.insert(std::make_pair(3, "Hello"));

if( ret.second)
{ 
    //the value is inserted
}
else
{
    //no value is inserted
}

The return value indicates whether the value is already present or not. If it is not present, the value will be inserted, else no value will be inserted.

Taken from here:

... returns a pair, with its member pair::first set to an iterator pointing to either the newly inserted element or to the element that already had its same value in the map. The pair::second element in the pair is set to true if a new element was inserted or false if an element with the same value existed.

like image 174
Nawaz Avatar answered Dec 23 '22 16:12

Nawaz


Do not overwrite previous values, what to use?

std::map<T1,T2>::insert already does this check for you, if there already is an entry with the specified key the insert will be aborted.

  std::map<int, std::string> m;

  m.insert (std::make_pair (3, "hello world"));
  m.insert (std::make_pair (3, "world hello"));

  std::cerr << m[3] << std::endl;

output:

  hello world

Was the new value inserted?

std::map<T1,T2>::insert returns a std::pair<std::map<T1,T2>::iterator, bool>, the 2nd value (pair.second) will act as a flag saying if the key/value pair was inserted or not.

if ret.second ==  true: value was inserted
if ret.second == false: the key has already been set

example snippet:

  std::cerr << m.insert (std::make_pair (1,1)).second << std::endl;
  std::cerr << m.insert (std::make_pair (1,2)).second << std::endl;

output

  1
  0
like image 40
Filip Roséen - refp Avatar answered Dec 23 '22 18:12

Filip Roséen - refp