Что состоит в том, чтобы определить лучший способ, содержит ли карта 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;
}
Что-то вдоль этих строк существует?
Существует ли что-нибудь в этом роде?
Нет. С классом карты 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);
Он уже существует с 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;
}
amap.find
возвращает amap :: end
, если не находит то, что вы ищете - вы должны это проверить.
Проверьте возвращаемое значение find
против end
.
map<int, Bar>::iterator it = m.find('2');
if ( m.end() != it ) {
// contains
...
}
Вы можете создать свою функцию 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;
}