假设我有一个unordered_map<string, int> H
。
假设H中没有元素" House",因此cout<<H["house"];
会打印0。
,假设我需要分配H["house"] = 0
。
我将如何区分一个不存在的元素与0?
//example of what I want:
if(!H["house"]){
cout<<"DOES NOT EXIST YETn";
H["house"] = 0;
}
if(H["house"]){
cout<<"IT EXISTS NOWn";
}
在std::unordered_map
中,operator[]
如果不存在元素,则修改地图。这是为了允许诸如H["house"] = 0
之类的简单分配语句工作。查找时,您真的不想要这个。
相反,您应使用H.find
,或使用H.at
。find
返回一个迭代器,如果找不到元素,它将等于H.end()
,否则可以为该值删除。如果找不到元素,则at
会引发错误。
最短测试:
if (H.count("house")) {
// "house" exists
} else {
// "house" does not exist in H
}
auto itr = H.find("house");
if (itr == H.end())
{
// "house" does not exist in H
}
else
{
// "house" exists
// itr->second = the same as H["house"]
}
如果您可以访问boost
,则可以将可选参考返回映射类型的小功能很有用。如果您有最近的C 实现,则可以使用std::optional
。
template<class K, class V, class H, class E, class A, class Lookup>
auto
maybe_at(std::unordered_map<K,V,H,E,A> const& m, Lookup&& key)
-> boost::optional<V const&>
{
boost::optional<V const&> result;
auto i = m.find(key);
if (i != m.end())
result = i->second;
return result;
}
使用的示例:
#include <unordered_map>
#include <boost/optional.hpp>
#include <iostream>
#include <string>
template<class K, class V, class H, class E, class A, class Lookup>
auto
maybe_at(std::unordered_map<K,V,H,E,A> const& m, Lookup&& key)
-> boost::optional<V const&>
{
boost::optional<V const&> result;
auto i = m.find(key);
if (i != m.end())
result = i->second;
return result;
}
void emit(boost::optional<const int&> oi)
{
if (oi)
{
std::cout << *oi << std::endl;
}
else
{
std::cout << "{null}" << std::endl;
}
}
int main()
{
std::unordered_map<std::string, int> m;
m["house"] = 0;
emit(maybe_at(m, "house"));
emit(maybe_at(m, "donkey"));
}