c++ - 可变参数模板求和运算左关联

标签 c++ templates sum variadic-templates decltype

下面的代码适用于:左结合求和运算的目标:sum(1,2,3,4);

但是,对于 sum(1,2,3,4,5)sum(1,2,3,4,5,... )。超过 4 个参数的任何内容都会出现错误:

error: no matching function for call to sum(int, int, int, int, int)

=================================

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); //works correctly
    //cout << sum(1,2,3,4,5); //compile error

}

最佳答案

这似乎是 GCC 中的一个错误,当使用可变参数模板、自动返回类型和对尾随返回类型中相同可变参数模板的递归引用时。

C++11 - 只有右结合

它是可以解决的,通过良好的旧模板元编程:

//first a metafunction to calculate the result type of sum(Ts...)
template <typename...> struct SumTs;
template <typename T1> struct SumTs<T1> { typedef T1 type; };
template <typename T1, typename... Ts>
struct SumTs<T1, Ts...>
{
  typedef typename SumTs<Ts...>::type rhs_t;
  typedef decltype(std::declval<T1>() + std::declval<rhs_t>()) type;
};

//now the sum function
template <typename T>
T sum(const T& v) {
  return v;
}

template <typename T1, typename... Ts>
auto sum(const T1& v1, const Ts&... rest) 
  -> typename SumTs<T1,Ts...>::type //instead of the decltype
{
  return v1 + sum(rest... );
}

#include <iostream>
using std::cout;

int main() {
  cout << sum(1,2,3,4,5);    
}

PS:为了更通用,整个事情可以用“通用引用”和 std::forward 来修饰。

C++17 折表达式

在C++17中,基本上一行就可以解决问题:

template<typename T, typename... Ts>
constexpr auto sum(T&& t, Ts&&... ts) 
{
  return (std::forward<T>(t) + ... + std::forward<Ts>(ts));
}
``

关于c++ - 可变参数模板求和运算左关联,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16663866/

相关文章:

c++ - 使用 qsort 对字符串进行排序不起作用

c++ - 借助 static_assert 改进诊断

python - 对列表列表中的元素求和并在 Python 中找到最大值

c++ - 求 K 个不同整数处多项式的值,模 786433

c# - 将 MFC COM 服务器移植到托管代码的最佳方式

c++ - 如何在 OpenGL/C++ 中创建构造实体几何

templates - Express 和 Jade 的模板继承

C++编译错误

perl - 如何在perl中添加小时,分钟,秒

php - 使用 MySQLi 求和的单个结果