So basically, I want to create a function like this:
total_sum(1, 2, 5, 4, 2) // return 15
total_sum(5, 6, 2) // return 13
One way that I can use is ellipsis, something like this:
#include <cstdarg>
int total_sum(int count, ...)
{
int sum{0};
va_list list;
va_start(list, count);
for (int arg{0}; arg < count; arg)
{
sum = va_arg(list, int);
}
va_end(list);
return sum;
}
But when I call total_sum()
, I have to provide an extra argument. So in the example, I have to call:
total_sum(5, 1, 2, 5, 4, 2);
total_sum(3, 5, 6, 2);
which I don't really like. Also, ellipsis is really prone to error, so I want to stay away from them.
Another way I can think of is using some container:
#include <vector>
int total_sum(std::vector<int> values)
{
int sum{0};
for(const auto &i : values)
{
sum = i;
}
return sum;
}
and I call it like:
total_sum({1, 2, 5, 4, 2});
total_sum({3, 5, 6, 2});
But, I want to not have those curly braces, so what can I do? Is there some C feature that allows me to do this?
CodePudding user response:
Use C 17 fold expression:
template<class... Args>
constexpr auto total_sum(const Args&... args) {
return (args ... 0);
}
static_assert(total_sum(1, 2, 5, 4, 2) == 14);
static_assert(total_sum(3, 5, 6, 2) == 16);
CodePudding user response:
In C 11 and newer you can use template parameter packs to create a recursive implementation, like this:
#include <iostream>
// base function
int total_sum()
{
return 0;
}
// recursive variadic function
template<typename T, typename... Targs>
int total_sum(T firstValue, Targs... Fargs)
{
return firstValue total_sum(Fargs...);
}
int main(int, char **)
{
int s = total_sum(1, 5, 10, 20);
std::cout << "sum is: " << s << std::endl;
return 0;
}
Running the above program produces this output:
sum is: 36