c++ - variadic templates sum operation left associative -
the code below works the: goal left associative sum operation: sum(1,2,3,4);
however, won't work correctly sum(1,2,3,4,5)
or sum(1,2,3,4,5,...)
. more 4 arguments gives error:
error: no matching function call 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 }
that seems bug in gcc, when working variadic templates, auto return types , recursive reference same variadic template in trailing return type.
it solvable, through old template meta programming:
//first metafunction calculate 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 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 decltype { return v1 + sum(rest... ); } #include <iostream> using std::cout; int main() { cout << sum(1,2,3,4,5); }
ps: more generic, whole thing pimped "universal references" , std::forward
.
update: used std::declval
instead of handwritten functions
Comments
Post a Comment