Pergunta

I can't get this rather simple code to compile. I get the error, could not deduce template argument for 'std::basic_string<_Elem,_Traits,_Alloc> &&' from 'int'. Do I need to pass some custom summing function to accumulate? Or perhaps is there a simpler way to get the sum of all second values in the map? Thanks!

#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;
}
Foi útil?

Solução

You may not use algorithm std::accuulate in its simple form for a container of type std::map. You need use the algorithm with binary operation and to use possibly a lambda expression as the binary operation. For example

int sum = accumulate( m.begin(), m.end(), 0,
                      []( int acc, std::pair<int, int> p ) { return ( acc + p.second ); } );

Outras dicas

Element type of std::map<K,V> is std::pair<const K,V> for which operator+ is not defined. You need to use 4 argument version of accumulate and supply your own addition operation:

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

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

An std::map<int, int> contains std::pair<const int, int> elements. std::accumulate does not know what to do with those. But you can fix this problem by passing it a suitable functor. For example, to accumulate the keys:

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

Note you can simplify this by using a lambda, if you don't need to use fun anywhere else:

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

Alternatively, you could use lambda expression with map<int,int>::value_type as the binary operation.

sum = accumulate(m.begin(), m.end(), 0, 
                [](int v, map<int,int>::value_type& p) { return v + p.second; });
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top