Reputation: 782
I have the following code with a variadic template copied from: https://www.youtube.com/watch?v=iWvcoIKSaoc @41:30
auto sum() { return 0; }
template<typename Head, typename... Tail>
auto sum(Head head, Tail... tail)
{
return head+sum(tail...);
}
int main() {
cout<< sum(1,2.4) << endl;
//cout<< sum("hello ", "world") << endl;
return 0;
}
I have two questions: 1. The sum() function is required here so that I can have a return value for a void passed in when processing the last variadic member - Is it possible to avoid writing this sum() function and have the same functionality?
Thank You
Upvotes: 4
Views: 193
Reputation: 171127
- The
sum()
function is required here so that I can have a return value for avoid
passed in when processing the last variadic member - Is it possible to avoid writing thissum()
function and have the same functionality?
Every recursion needs a stop condition. In the typical use of recursion with variadic templates (such as in this code), the stop condition is a different overload of the primary template. So you cannot get rid of this entirely.
You can of course replace the stop condition with a different one. Perhaps this one, which will also work for summing things which are not default-constructible:
template <class T>
auto sum(T last) { return last; }
Of course, there are other approaches to this than recursive variadic templates; such approaches may not need a stop condition.
- Returning a integer '0' from the
sum()
function restricts the entire template to be used by integers - Can I extend the same template to concatenate strings?
No, because the non-template function has no knowledge of which type the previous recursive invocations were dealing with. This can be solved by using the "last item" stop condition I suggested above.
Upvotes: 1
Reputation: 2053
To complement @GuillaumeRacicot answer I prefer to end a recursion with if constexpr
which is a c++17
feature.
template<typename Head, typename Second, typename... Tail>
auto sum(Head head, Second second, Tail... tail)
{
if constexpr(sizeof...(tail) > 0)
return head + sum(second, tail...);
return head + second;
}
You can also consider fold expressions:
template<typename ...Pack>
auto sum(Pack... args) {
return (args + ...);
}
Upvotes: 6
Reputation: 41760
The trick is to never allow empty sum()
calls, and treat the sum(last)
as the last recursion:
template<typename Last>
auto sum(Last last) {
return last;
}
template<typename Head, typename Second, typename... Tail>
auto sum(Head head, Second second, Tail... tail)
{
return head + sum(second, tail...);
}
int main() {
cout<< sum(1,2.4) << endl;
cout<< sum("hello ", "world") << endl;
return 0;
}
Upvotes: 3