为什么和是0
Why is the sum 0?
本文关键字:为什么 更新时间:2023-10-16
我正在尝试创建一个通用和函数模板。这个模板是left associative
。下面是我的实现
int result=0;
template <typename D, typename T>
const T &sum_helper(const D &d, const T &v) {
result=result+v;
return result;
}
int pass(...){}
template <typename D, typename T1, typename... Ts>
auto sum_helper(const D &d, const T1 &v1, const Ts &... params) -> decltype(v1 + sum_helper(d, params...)) {
return v1 + sum_helper(d, params... );
}
class A {};
template <typename... Ns>
struct seq {};
template <typename... Ts>
auto sum(const Ts &... params) -> decltype(sum_helper(A(), params...))
{
return pass((sum_helper(seq<Ts...>(),params)) ...,1);
}
但是当我把它叫做sum(1,2,3,4)
时它总是输出0
。什么错了吗?我知道pass
应该改正。但是怎样才能纠正呢?
原来的答案不起作用,因为后面的返回类型在声明点之前使用了重载。在知道函数的返回类型之前,也不可能向前声明函数。所以我们需要一个helper结构体。下面是工作的(不幸的是现在非常复杂)版本:
#include <utility>
template <typename...>
struct sum_impl;
/* This is the base case */
template <typename T1, typename T2>
struct sum_impl<T1, T2>
{
typedef decltype(std::declval<const T1&>() + std::declval<const T2&>()) result_type;
static result_type doit(const T1& v1, const T2& v2)
{
return v1 + v2;
}
};
/* And here is the recursive definition for left-associativity */
template <typename T1, typename T2, typename... Ts>
struct sum_impl<T1, T2, Ts...>
{
typedef decltype(std::declval<const T1&>() + std::declval<const T2&>()) step_type;
typedef typename sum_impl<step_type, Ts...>::result_type result_type;
static result_type doit(const T1& v1, const T2& v2, const Ts&... rest)
{
return sum_impl<step_type, Ts...>::doit(v1 + v2, rest...);
}
};
template <typename... Ts>
typename sum_impl<Ts...>::result_type sum(const Ts&... args)
{
return sum_impl<Ts...>::doit(args...);
}
演示:http://ideone.com/jMwgLz
下面这个版本保留了Named答案的简单性,但是是左结合的:
/* not really needed, unless someone wants to call sum with only a single argument */
template <typename T>
T sum(const T& v)
{
return v;
}
/* This is the base case */
template <typename T1, typename T2>
auto sum(const T1& v1, const T2& v2) -> decltype( v1 + v2 )
{
return v1 + v2;
}
/* And here is the recursive definition for left-associativity */
template <typename T1, typename T2, typename... Ts>
auto sum(const T1& v1, const T2& v2, const Ts&... rest) -> decltype( sum(v1 + v2, rest...) )
{
return sum(v1 + v2, rest... );
}
有一个更简单的解决方案:
#include <iostream>
using namespace std;
template <typename T1>
auto _sum(T1 & _ret, const T1 & _t1) -> T1
{
_ret += _t1;
return _ret;
}
template <typename T1, typename... Ts>
auto _sum(T1 & _ret, const T1 & _t1, const Ts &... params) -> T1
{
_ret += _t1;
return _sum(_ret, params...);
}
template <typename T1, typename... Ts>
auto sum(const T1 & _t1, const Ts &... params) -> T1
{
T1 ret = _t1;
return _sum(ret, params...);
}
int main()
{
cout << sum(1, 2, 3, 4, 5) << endl;
return 0;
}
但是当我把它叫做sum(1,2,3,4)时,它总是输出0。什么错了吗?
这是因为pass
是不返回任何东西所以你这里有什么是未定义行为,因为你正在流出一个非空函数,不返回任何东西。
我不知道你为什么在这里需要pass
return pass((sum_helper(seq<Ts...>(),params)) ...,1);
您可以展开可变参数并将它们直接发送给sum_helper
。这样的
return sum_helper(seq<Ts...>(),params...);
但是更简单的版本应该是
template <typename T>
T sum(const T& v) {
return v;
}
template <typename T1, typename T2>
auto sum(const T1& v1, const T2& v2) -> decltype( v1 + v2) {
return v1 + v2;
}
template <typename T1, typename T2, typename... Ts>
auto sum(const T1& v1, const T2& v2, const Ts&... rest) -> decltype( v1 + v2 + sum(rest...) ) {
return v1 + v2 + sum(rest... );
}
int main() {
cout << sum(1,2,3,4);
}
Rollie的回答提供了一个更简单的版本
相关文章:
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 为什么在全局范围内使用"extern int a"似乎不行?
- 为什么在popback()操作之后,它仍然打印完整的矢量
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 为什么会发生堆损坏
- 为什么使用 "this" 指针调用派生成员函数?
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 为什么比较运算符如此快速
- 为什么 Serial.println(<char[]>);返回随机字符?
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 为什么不;名字在地图上是按顺序排列的吗
- 我的字符计数代码计算错误.为什么
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 为什么野牛仍在使用"int yylex(void)",却找不到"int yylex(YYS
- 为什么 std::unique 不调用 std::sort?
- 既然存在危险,为什么项目要使用-I include开关
- 为什么在运行时没有向我们提供有关分段错误的更多信息?