确定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 map类,您使用::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,这导致'2'的ASCII代码的数值,这不是你想要的。
由于你在这个例子中的keytype是int
,你想这样搜索:m.find(2);
Boost multindex可用于正确解决方案。以下解决方案不是一个非常好的选项,但在用户在初始化时分配默认值(如0或NULL)并且想要检查值是否已被修改的少数情况下可能很有用。
Ex.
< int , string >
< string , int >
< string , string >
consider < string , string >
mymap["1st"]="first";
mymap["second"]="";
for (std::map<string,string>::iterator it=mymap.begin(); it!=mymap.end(); ++it)
{
if ( it->second =="" )
continue;
}
只要地图不是多图,最优雅的方法之一就是使用count方法
if (m.count(key))
// key exists
如果元素确实存在于地图中,则计数将为1。
它已经存在,只有查找不是那种确切的语法。
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;
}
简洁地总结一些其他答案:
如果你还没有使用C ++ 20,你可以编写自己的mapContainsKey
函数:
bool mapContainsKey(std::map<int, int> map, int key)
{
if (map.find(key) == map.end()) return false;
return true;
}
如果你想避免map
和unordered_map
以及不同的键和值类型的许多重载,你可以使它成为template
函数。
如果你正在使用C++ 20
或更高版本,将会有一个内置的contains
功能:
std::map<int, int> myMap;
// do stuff with myMap here
int key = 123;
if (myMap.contains(key))
{
// stuff here
}
如果要确定某个键是否存在于映射中,可以使用map的find()或count()成员函数。这里使用的find函数返回迭代器到element或map :: end。在计数的情况下,如果找到则计数返回1,否则返回零(或其他)。
if(phone.count(key))
{ //key found
}
else
{//key not found
}
for(int i=0;i<v.size();i++){
phoneMap::iterator itr=phone.find(v[i]);//I have used a vector in this example to check through map you cal receive a value using at() e.g: map.at(key);
if(itr!=phone.end())
cout<<v[i]<<"="<<itr->second<<endl;
else
cout<<"Not found"<<endl;
}