Подпись std::accumulate
:
T accumulate( InputIt first, InputIt last, T init,
BinaryOperation op );
Обратите внимание, что возвращаемое значение выводится из параметра init
(это не обязательно value_type
из InputIt
).
Двоичная операция:
Ret binary_op(const Type1 &a, const Type2 &b);
, где ... (из cppreference ) ...
Тип Type1
должен бытьтакой, что объект типа T
может быть неявно преобразован в Type1
. Тип Type2
должен быть таким, чтобы объект типа InputIt
мог быть разыменован, а затем неявно преобразован в Type2
. Тип Ret
должен быть таким, чтобы объекту типа T
можно было присвоить значение типа Ret
.
Однако, когда T
является value_type
из InputIt
, вышеприведенное проще и у вас есть:
using value_type = std::iterator_traits<InputIt>::value_type;
T binary_op(T,value_type&).
Предполагается, что ваш конечный результат будет int
, следовательно, T
равно int
. Вам нужно два вызова: два std::accumulate
, один для внешнего вектора (где value_type == std::vector<int>
) и один для внутренних векторов (где value_type == int
):
#include <iostream>
#include <numeric>
#include <iterator>
#include <vector>
template <typename IT, typename T>
T accumulate2d(IT outer_begin, IT outer_end,const T& init){
using value_type = typename std::iterator_traits<IT>::value_type;
return std::accumulate( outer_begin,outer_end,init,
[](T accu,const value_type& inner){
return std::accumulate( inner.begin(),inner.end(),accu);
});
}
int main() {
std::vector<std::vector<int>> x{ {1,2} , {1,2,3} };
std::cout << accumulate2d(x.begin(),x.end(),0);
}