C++ unordered_map<T, int>如何区分空单元格和0
C++ unordered_map<T, int> how to distinguish null cell from 0
假设我有一个 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 YET\n";
H["house"] = 0;
}
if(H["house"]){
cout<<"IT EXISTS NOW\n";
}
在 std::unordered_map
中,如果元素不存在,operator[]
修改映射。这是为了允许像 H["house"] = 0
这样的简单赋值语句起作用。查的时候真的不要这个
相反,您应该使用 H.find
,或使用 H.at
。 find
returns 一个迭代器,如果找不到元素,它将与 H.end() 进行比较,否则可以取消引用该值。 at
如果找不到该元素,则抛出错误。
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"]
}
最短测试:
if (H.count("house")) {
// "house" exists
} else {
// "house" does not exist in H
}
如果您有权访问 boost
,那么 return 对映射类型的可选引用的一个小函数可能会有用。如果你有最近的 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"));
}
假设我有一个 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 YET\n";
H["house"] = 0;
}
if(H["house"]){
cout<<"IT EXISTS NOW\n";
}
在 std::unordered_map
中,如果元素不存在,operator[]
修改映射。这是为了允许像 H["house"] = 0
这样的简单赋值语句起作用。查的时候真的不要这个
相反,您应该使用 H.find
,或使用 H.at
。 find
returns 一个迭代器,如果找不到元素,它将与 H.end() 进行比较,否则可以取消引用该值。 at
如果找不到该元素,则抛出错误。
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"]
}
最短测试:
if (H.count("house")) {
// "house" exists
} else {
// "house" does not exist in H
}
如果您有权访问 boost
,那么 return 对映射类型的可选引用的一个小函数可能会有用。如果你有最近的 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"));
}