通常,如果您进行查找和插入操作,那么如果已经存在,则要保留(并检索)旧值。如果您只想覆盖旧值,map[foo_obj]="some value"
可以实现这一点。
以下是如何使用一个 map 查找获取旧值或插入新值(如果不存在):
typedef std::map<Foo*,std::string> M;
typedef M::iterator I;
std::pair<I,bool> const& r=my_map.insert(M::value_type(foo_obj,"some value"));
if (r.second) {
} else {
}
这是一个常见的习语,您可能希望使用一个辅助函数:
template <class M,class Key>
typename M::mapped_type &
get_else_update(M &m,Key const& k,typename M::mapped_type const& v) {
return m.insert(typename M::value_type(k,v)).first->second;
}
get_else_update(my_map,foo_obj,"some value");
如果您有一个昂贵的计算方式用于v,如果它已经存在就想要跳过它(例如记忆化),那么您也可以进行推广:
template <class M,class Key,class F>
typename M::mapped_type &
get_else_compute(M &m,Key const& k,F f) {
typedef typename M::mapped_type V;
std::pair<typename M::iterator,bool> r=m.insert(typename M::value_type(k,V()));
V &v=r.first->second;
if (r.second)
f(v);
return v;
}
例如,其中
struct F {
void operator()(std::string &val) const
{ val=std::string("some value")+" that is expensive to compute"; }
};
get_else_compute(my_map,foo_obj,F());
如果映射类型不可默认构造,则需要使F提供一个默认值,或者在get_else_compute中添加另一个参数。