This seems like a mistake in GCC when working with variable templates, automatic return types, and a recursive reference to the same variable template at the end of the return type.
C ++ 11 - only associative law
This can be solved using the good old meta-programming template:
//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... ); }
PS: to be even more universal, all this could be denoted by "universal links" and std::forward .
C ++ 17 multiple expressions
In C ++ 17, the problem can be solved mainly in one line:
template<typename T, typename... Ts> constexpr auto sum(T&& t, Ts&&... ts) { return (std::forward<T>(t) + ... + std::forward<Ts>(ts)); } ''
Arne mertz
source share