I wanted to write a fold function for std::tuple that can compute e.g. the sum (or product) of all the elements in a given tuple. For example, given
std::tuple<int,double> t = std::make_tuple(1,2);
I'd like to compute
auto s = sumT(t); //giving 3
I tried but couldn't get my template programming (c++11/1z) code below to compile. I also tried to adapt the accepted answer for my other question (How to perform tuple arithmetic in C++ (c++11/c++17)?), but can't figure out how to use std::index_sequence in this case.
The issues I have are:
1) I can't figure out the types, e.g. how to use the type of the first element as the return type. Currently, I use a _res type in the template, but I don't know if that will block c++'s auto type-inferencing.
2) I'd like to program this without using an explicit initial element 0, so that this can be used for other kinds of fold operations.
Currently, the recursion ends at the last element. I'd like to end the recursion at _size - 1 so that I can directly perform the operation on the last element without resorting to 0.
The code I have below tries to do this by recursion. But I don't know template programming well, and how the loops work for tuples.
Can someone help fix the code or come up with a better solution?
My code so far is:
#include <tuple>
#include <iostream>
#include <functional>
// helper class for fold operations
template<typename Op,typename _res, typename _Tp, size_t _i, size_t _size>
struct _tuple_fold {
static constexpr _res _op(Op const & op, const _Tp& _t) {
return _res(op(std::get<_i>(_t),
_tuple_fold<Op, _res, _Tp, _i + 1, _size>::_op(op,_t) ));
}
};
template<typename Op,typename _res,typename _Tp, size_t _size>
struct _tuple_fold<Op, _res,_Tp, _size, _size> {
static constexpr _res _op(Op const &, const _Tp&) { return 0; }
};
template <typename ... Ts>
auto sumT (std::tuple<Ts...> const & t1) {
return _tuple_fold::_op(std::plus<>{}, t1);
}
int main () {
std::tuple<int,double> t = std::make_tuple(1,2);
auto s = sumT(t);
std::cout << s << std::endl;
}
The error messages for compiling with g++ -std=c++17 tuple_sum.cpp:
tuple_sum.cpp: In function ‘auto sumT(const std::tuple<_Elements ...>&)’:
tuple_sum.cpp:21:10: error: ‘template<class Op, class _res, class _Tp, long unsigned int _i, long unsigned int _size> struct _tuple_fold’ used without template parameters
return _tuple_fold::_op(std::plus<>{}, t1);
^
tuple_sum.cpp: In function ‘int main()’:
tuple_sum.cpp:27:19: error: ‘void s’ has incomplete type
auto s = sumT(t);
^
I'm not sure how to supply the type parameters for _tuple_fold on the call site, especially the type for std::plus.