Can I create a function which takes any number of arguments of the same type?
Solution 1:
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);
Solution 2:
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
Solution 3:
All of the code below is is based on this article.
You can also do this kind-of C++11 "equivalent" of fold expressions:
#include <iostream>
#include <algorithm>
#include <utility>
#include <type_traits>
/*
Overload a total_sum() function with no arguments.
so it works when calling total_sum() with no argument.
*/
int total_sum()
{
return 0;
}
template<typename ... I>
int total_sum(const I &... i)
{
int result{};
static_cast<void>(std::initializer_list<int>{(result += i, 0)... });
return result;
}
int main()
{
std::cout << total_sum() << '\n';
std::cout << total_sum(1, 2, 5, 4, 2) << '\n';
std::cout << total_sum(5, 6, 2) << '\n';
}
See this online!
This one can add anything that can convert to an add-able value:
#include <iostream>
#include <algorithm>
#include <utility>
#include <type_traits>
int total_sum()
{
return 0;
}
template<typename ... V>
typename std::common_type<V...>::type total_sum(const V &... v)
{
typename std::common_type<V...>::type result = {};
static_cast<void>(std::initializer_list<int>{ (result += v, 0)... });
return result;
}
int main()
{
std::cout << total_sum() << '\n';
std::cout << total_sum(5, 6, 2) << '\n';
}
See this online!
The code above can be cleaner using C++14:
#include <iostream>
#include <algorithm>
#include <utility>
#include <type_traits>
int total_sum()
{
return 0;
}
template<typename ... V>
auto total_sum(const V &... v) {
std::common_type_t<V...> result = {};
static_cast<void>(std::initializer_list<int>{ (result += v, 0)... });
return result;
}
int main()
{
std::cout << total_sum() << '\n';
std::cout << total_sum(5, 6, 2) << '\n';
}
See this online!