I am simply trying to add values of a map defined in the program below:
std::map<int, int> floor_plan;
const size_t distance = std::accumulate(std::begin(floor_plan), std::end(floor_plan), 0);
std::cout << "Total: " << distance;
I get the following error:
Error C2893: Failed to specialize function template 'unknown-type std::plus::operator ()(_Ty1 &&,_Ty2 &&) const'
std::begin(floor_plan)
gives you an iterator pointing at std::map<int, int>::value_type
which is std::pair<const int, int>
. Since there is no operator+
defined for this pair type and an integer, your code fails to compile.
If you want to sum up all the mapped values from floor_plan
, you'd need to provide your own binary operator that is able to extract the second element of a dereferenced iterator passed in:
std::accumulate(std::begin(floor_plan)
, std::end(floor_plan)
, 0
, [] (int value, const std::map<int, int>::value_type& p)
{ return value + p.second; }
);
Alternatively, you could exploit the Boost.Iterator library to extract the second element of a pair on the fly with boost::make_transform_iterator
:
#include <boost/iterator/transform_iterator.hpp>
#include <functional>
auto second = std::mem_fn(&std::map<int, int>::value_type::second);
std::accumulate(boost::make_transform_iterator(std::begin(floor_plan), second)
, boost::make_transform_iterator(std::end(floor_plan), second)
, 0);
Another approach is to use the Boost.Range library along with its own implementation of the accumulate
algorithm:
#include <boost/range/numeric.hpp>
#include <boost/range/adaptor/map.hpp>
boost::accumulate(floor_plan | boost::adaptors::map_values, 0);