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

Daq*_*aqs 14 c++ dictionary accumulate c++11

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

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;
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

错误C2893:无法专门化函数模板'unknown-type std :: plus :: operator()(_ Ty1 &&,_ Ty2 &&)const'

Pio*_*cki 21

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; }
               );
Run Code Online (Sandbox Code Playgroud)

演示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);
Run Code Online (Sandbox Code Playgroud)

演示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);
Run Code Online (Sandbox Code Playgroud)

演示3

  • @Daqs`std :: next(std :: begin(floor_plan),3)`代替`std :: begin` (3认同)