C ++ STL map - условная вставка - PullRequest
4 голосов
/ 17 декабря 2011

Я ищу эффективный способ сделать условную вставку.В идеале я хотел бы, чтобы функция шаблона работала на любой карте.Я хочу что-то вроде этого:

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
}

Я не могу легко использовать operator[], потому что нет простого способа узнать, создал ли он элемент или нет.Я могу использовать count для теста, но тогда мне придется дважды искать карту, если мы сделаем вставку.Думаю, что-то с find было бы лучше, но всегда кажется, что это блекло и неловко.

Есть ли действительно хороший способ сделать это?

Ответы [ 3 ]

5 голосов
/ 17 декабря 2011

Не перезаписывать предыдущие значения, что использовать?

std::map<T1,T2>::insert уже делает эту проверку для вас, если уже есть запись с указанным ключом, вставка будет прервана.

  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;

вывод:

  hello world

Было ли введено новое значение?

std::map<T1,T2>::insert возвращает std::pair<std::map<T1,T2>::iterator, bool>, второе значение (pair.second) будет действовать как флаг, указывающий, была ли вставлена ​​пара ключ / значение.

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

пример фрагмента:

  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
5 голосов
/ 17 декабря 2011

Какую проблему вы видите с этим:

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

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

Возвращаемое значение указывает, присутствует ли значение уже или нет.Если его нет, значение будет вставлено, иначе значение не будет вставлено.

Взято из здесь :

... возвращает парус его параметром pair :: first, установленным в итератор, указывающий либо на недавно вставленный элемент, либо на элемент, который уже имел то же значение на карте. Элемент pair :: second в паре устанавливается в значение true, если был вставлен новый элемент, или в значение false, если существовал элемент с таким же значением.

1 голос
/ 17 декабря 2011

Функция insert уже делает то, что вы хотите.

std::pair<std::map<int, std::string>::iterator, bool>
    insertionResult = MyMap.insert(std::make_pair(3, "Hello"));

if(insertionResult.second)
{ // 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
}

Первый элемент пары дает местоположение элемента с ключом, старый или новый.

...