【发布时间】:2018-04-23 06:51:39
【问题描述】:
我想为std::tuple 编写一个fold 函数,它可以计算例如给定元组中所有元素的总和(或乘积)。例如,给定
std::tuple<int,double> t = std::make_tuple(1,2);
我想计算
auto s = sumT(t); //giving 3
我尝试过但无法编译下面的模板编程 (c++11/1z) 代码。我还尝试为我的其他问题 (How to perform tuple arithmetic in C++ (c++11/c++17)?) 调整已接受的答案,但在这种情况下无法弄清楚如何使用 std::index_sequence。
我遇到的问题是:
1) 我不知道类型,例如如何使用第一个元素的类型作为返回类型。目前,我在模板中使用了_res 类型,但我不知道这是否会阻止 c++ 的自动类型推断。
2) 我想在不使用显式初始元素0 的情况下对此进行编程,以便可以将其用于其他类型的fold 操作。
目前,递归在最后一个元素处结束。我想在_size - 1 处结束递归,这样我就可以直接对最后一个元素执行操作,而无需诉诸0。
我下面的代码尝试通过递归来做到这一点。但我不太了解模板编程,以及循环如何处理元组。
有人可以帮助修复代码或提出更好的解决方案吗?
到目前为止我的代码是:
#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;
}
使用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);
^
我不确定如何在调用站点上为_tuple_fold 提供类型参数,尤其是std::plus 的类型。
【问题讨论】:
-
std::accumulate 带有 lambda 我认为应该做得很好。
-
@JesperJuhl 不,你不能从以太容器中获取常用的迭代器(比如 tuple
)