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!