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
.