使用 std::accumulate 添加 map 的所有值

新手上路,请多包涵

我只是想添加下面程序中定义的地图的值:

 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;

我收到以下错误:

错误 C2893:无法专门化函数模板 ‘unknown-type std::plus::operator ()(_Ty1 &&,_Ty2 &&) const’

原文由 Daqs 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 801
1 个回答

std::begin(floor_plan) 给你一个指向 std::map<int, int>::value_type 的迭代器,即 std::pair<const int, int> 。由于没有为此对类型和整数定义 operator+ ,因此您的代码无法编译。

选项1

如果您想总结 floor_plan 中的所有映射值,您需要提供自己的二元运算符,该运算符能够提取传入的取消引用迭代器的第二个元素:

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

演示 1

选项#2

或者,您可以利用 Boost.Iterator 库使用 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);

演示 2

选项#3

另一种方法是使用 Boost.Range 库以及它自己的 accumulate 算法实现:

 #include <boost/range/numeric.hpp>
#include <boost/range/adaptor/map.hpp>

boost::accumulate(floor_plan | boost::adaptors::map_values, 0);

演示 3

原文由 Piotr Skotnicki 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题