c ++ map find()to possible insert():如何优化操作? [英] c++ map find() to possibly insert(): how to optimize operations?

查看:251
本文介绍了c ++ map find()to possible insert():如何优化操作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用STL地图数据结构,目前我的代码首先调用 find():如果键之前不在地图中,它调用 insert() ,否则它什么都不做。

I'm using the STL map data structure, and at the moment my code first invokes find(): if the key was not previously in the map, it calls insert() it, otherwise it does nothing.

map<Foo*, string>::iterator it;
it = my_map.find(foo_obj);   // 1st lookup

if(it == my_map.end()){
  my_map[foo_obj] = "some value";  // 2nd lookup
}else{
  // ok do nothing.
}



我想知道是否有一个比这更好的方法,因为我可以告诉,在这种情况下,当我想插入一个尚未存在的密钥,我在地图数据结构中执行2查找:一个 find(),一个在插入

I was wondering if there is a better way than this, because as far as I can tell, in this case when I want to insert a key that is not present yet, I perform 2 lookups in the map data structures: one for find(), one in the insert() (which corresponds to the operator[] ).

感谢您提出任何建议。

推荐答案

通常,如果你做一个查找和插入,那么你想保留(和检索)旧的值,如果它已经存在。如果你只是想覆盖任何旧的值, map [foo_obj] =一些值会这样做。

Normally if you do a find and maybe an insert, then you want to keep (and retrieve) the old value if it already existed. If you just want to overwrite any old value, map[foo_obj]="some value" will do that.

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) { 
    // value was inserted; now my_map[foo_obj]="some value"
} else {
    // value wasn't inserted because my_map[foo_obj] already existed.
    // note: the old value is available through r.first->second
    // and may not be "some value"
}
// in any case, r.first->second holds the current value of my_map[foo_obj]

您可能想要使用辅助函数:

This is a common enough idiom that you may want to use a helper function:

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你想跳过,如果它已经存在你可以概括一下:

If you have an expensive computation for v you want to skip if it already exists (e.g. memoization), you can generalize that too:

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;
}

其中eg

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());

如果映射类型不是默认可构造的,那么make F提供一个默认值,参数get_else_compute。

If the mapped type isn't default constructible, then make F provide a default value, or add another argument to get_else_compute.

这篇关于c ++ map find()to possible insert():如何优化操作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆