下面的代码适用于:左结合求和运算的目标: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/