Определите, содержит ли карта значение для ключа?

Что состоит в том, чтобы определить лучший способ, содержит ли карта STL значение для данного ключа?

#include <map>

using namespace std;

struct Bar
{
    int i;
};

int main()
{
    map<int, Bar> m;
    Bar b = {0};
    Bar b1 = {1};

    m[0] = b;
    m[1] = b1;

    //Bar b2 = m[2];
    map<int, Bar>::iterator iter = m.find(2);
    Bar b3 = iter->second;

}

Исследуя это в отладчике, это похоже iter просто данные мусора.

Если я некомментирую эту строку:

Bar b2 = m[2]

Отладчик показывает это b2 {i = 0}. (Я предполагаю, что это означает, что использование неопределенного индекса возвратит структуру со всеми пустыми/неинициализированными значениями?)

Ни один из этих методов не является настолько замечательным. То, что я действительно хотел бы, является интерфейсом как это:

bool getValue(int key, Bar& out)
{
    if (map contains value for key)
    {
        out = map[key];
        return true;
    }
    return false;
}

Что-то вдоль этих строк существует?

227
задан jww 24 August 2014 в 16:48
поделиться

5 ответов

Существует ли что-нибудь в этом роде?

Нет. С классом карты stl вы используете :: find () для поиска на карте и сравниваете возвращенный итератор с std :: map :: end ()

, поэтому

map<int,Bar>::iterator it = m.find('2');
Bar b3;
if(it != m.end())
{
   //element found;
   b3 = it->second;
}

Очевидно вы можете написать свою собственную процедуру getValue () , если хотите (также в C ++, нет причин использовать out ), но я подозреваю, что как только вы освоите использование std :: map :: find () вы не захотите тратить свое время зря.

Также ваш код немного неверен:

m.find ('2'); будет искать на карте ключевое значение, равное '2' . IIRC компилятор C ++ неявно преобразует '2' в int, что приводит к числовому значению для кода ASCII для '2', что не то, что вы хотите.

Поскольку ваш тип ключа в этом примере - int , вы хотите выполнить поиск следующим образом: m.find (2);

252
ответ дан 23 November 2019 в 03:48
поделиться

Он уже существует с find только не в том точном синтаксисе.

if (m.find(2) == m.end() )
{
    // key 2 doesn't exist
}

Если вы хотите получить доступ к значению, если оно существует, вы можете сделать:

map<int, Bar>::iterator iter = m.find(2);
if (iter != m.end() )
{
    // key 2 exists, do something with iter->second (the value)
}

С C ++ 0x и auto синтаксис проще:

auto iter = m.find(2);
if (iter != m.end() )
{
    // key 2 exists, do something with iter->second (the value)
}

Я рекомендую вам привыкнуть к нему, а не пытаться придумать с новым механизмом для его упрощения. Возможно, вы сможете сократить немного кода, но учитывайте затраты на это. Теперь вы представили новую функцию, которую люди, знакомые с C ++, не смогут распознать.

Если вы все равно хотите реализовать это, несмотря на эти предупреждения, тогда:

template <class Key, class Value, class Comparator, class Alloc>
bool getValue(const std::map<Key, Value, Comparator, Alloc>& my_map, int key, Value& out)
{
    typename std::map<Key, Value, Comparator, Alloc>::const_iterator it = my_map.find(key);
    if (it != my_map.end() )
    {
        out = it->second;
        return true;
    }
    return false;
}
50
ответ дан 23 November 2019 в 03:48
поделиться

amap.find возвращает amap :: end , если не находит то, что вы ищете - вы должны это проверить.

7
ответ дан 23 November 2019 в 03:48
поделиться

Проверьте возвращаемое значение find против end .

map<int, Bar>::iterator it = m.find('2');
if ( m.end() != it ) { 
  // contains
  ...
}
4
ответ дан 23 November 2019 в 03:48
поделиться

Вы можете создать свою функцию getValue с помощью следующего кода:

bool getValue(const std::map<int, Bar>& input, int key, Bar& out)
{
   std::map<int, Bar>::iterator foundIter = input.find(key);
   if (foundIter != input.end())
   {
      out = foundIter->second;
      return true;
   }
   return false;
}
1
ответ дан 23 November 2019 в 03:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: