2012-02-20 76 views
0

我有一个MAP可选择类型std :: map和可选的类型unordered_map(根据typdef MAP),以及一个函数,它将值添加到给定密钥的值:加速std :: map和boost:unordered_map []操作

func1(MAP<string, double> &map, string &key, double &val2add){ 
    try 
{ 
     map.at(key) += val2add; 
}catch(out_of_range& oor){ 
      map[key] = val2add; // in case map[key] didn't exist before. 
    } 
    } 

的问题是,这意味着不是简单

func2(MAP<string, double> &map, string &key, double &val2add){ 
     map[key] += val2add; // if map[key] doesn't exist - problem 
    } 

但上面是行不通的双(以及可能甚至更多)的工作,因为据我所知[]操作初始化与已定义的键映射的新对象,以及默认的double值。如果我知道默认的double值是0,那么func2仍然可以实现我想要的 - 但我不能依赖它。

那么有什么方法可以比func1更好地使用[]吗?

+2

我不明白你的问题是什么。如果key不存在,''std :: map'和'std :: unordered_map'的'operator []'保证为该值创建一个具有值初始化值的项。每个基本类型的值 - 初始化为0. – 2012-02-20 12:34:12

回答

7

第二段代码没有问题。如果未找到密钥,则[]将插入一个值初始化的对象(在这种情况下,值为零的double),并返回对该值的引用。因此,在这种情况下,map[key] += valuemap[key] = value具有相同的效果。

更一般地,它几乎肯定更高效的调用find,然后检查的结果,而不是调用at和捕获异常。异常处理实现通常假定异常只在特殊情况下抛出,并以非常规的代价优化通常情况。

当然,它的速度很重要,那么你需要测量它是肯定的。

+0

我以为我不能依靠默认的int,double值?我错了吗? – dan12345 2012-02-20 12:32:58

+2

@ dan12345 double的默认值是0.0,所以这就是你想要的。 (这与未初始化的变量非常不同,您的确无法依赖这些变量) – nos 2012-02-20 12:37:24

+0

@ dan12345:通常您可以依靠标准容器插入值初始化的值,而不是未初始化的值。当然,'operator []'的定义指定了“如果map中没有与'x'等价的键,则将'value_type(x,T())'插入到map中。” – 2012-02-20 12:41:33

2

你不能用operator[]做到这一点,但您可以使用insert方法:它返回迭代器,并指示是否返回的迭代点以前存在的元素或新插入的元素一个布尔值。

此外,原始类型默认初始化为零。

+0

不,原始类型*值*初始化为零。默认初始化使它们未初始化。 – 2012-02-20 13:15:42