在地图上累积数据

4

我无法编译这段相当简单的代码。我得到了错误信息:could not deduce template argument for 'std::basic_string<_Elem,_Traits,_Alloc> &&' from 'int'。我需要传递一些自定义求和函数给accumulate吗?或者也许有更简单的方法来获得映射中所有第二个值的总和?谢谢!

#include <iostream>
#include <math.h>
#include <map>
#include <numeric>  


int main()
{

map<int, int> m; 

m[1] = 1;
m[2] = -1;
m[3] = 1;
m[4] = 2;

int sum = accumulate(m.begin(), m.end(), 0);
cout << sum;

return 0;
}
4个回答

6
您不能简单地使用算法std::accumulate来处理类型为std::map的容器。您需要使用具有二元操作的算法,并可能使用lambda表达式作为二元操作。 例如:
int sum = accumulate( m.begin(), m.end(), 0,
                      []( int acc, std::pair<int, int> p ) { return ( acc + p.second ); } );

1

std::map<int, int>包含std::pair<const int, int>元素。std::accumulate不知道如何处理它们。但是您可以通过传递一个合适的函数对象来解决这个问题。例如,累加键:

int fun(int i, const std::pair<const int, int>& rhs)
{
  return i + rhs.second;
}
int sum = accumulate(m.begin(), m.end(), 0, fun);

请注意,如果您不需要在其他地方使用fun,可以使用lambda来简化此过程:
int sum = accumulate(m.begin(), m.end(),
                     [](int i, const std::pair<const int, int>& rhs)
                     {
                       return i + rhs.second;
                     });

它是std::pair<const Key, Value>。 - user2249683
@jrok 谢谢,我正在修复那个问题。 - juanchopanza
@DieterLücking 对的。已修复。 - juanchopanza

1

std::map<K,V>的元素类型是std::pair<const K,V>,其中未定义operator+。您需要使用4个参数版本的accumulate并提供自己的加法操作:

typedef std::pair<int, int> Pair;

int sum = accumulate(m.begin(), m.end(), 0,
    [](int i, Pair p){ return i + p.second; }); 

它是std :: pair <const Key,Value> - 但这在这里并不重要。 - user2249683
你是怎么解决的,亲爱的jrok,亲爱的jrok? - Yakk - Adam Nevraumont
@Yakk std::map<K,V> 的元素类型是 std::pair<const K,V>,请注意之前没有 const。如果这不是您的意思,那么您的意思是什么呢? :) - jrok
你的代码缺少修复。诚然,它只是复制,所以没有太大的危害。 - Yakk - Adam Nevraumont

0

或者,您可以使用lambda表达式和map<int,int>::value_type作为二元操作。

sum = accumulate(m.begin(), m.end(), 0, 
                [](int v, map<int,int>::value_type& p) { return v + p.second; });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接