Ed Barbu
Ed Barbu

Reputation: 1639

How do you create a variadic function that doesn't need the caller to pass arguments count to it?

EDIT: I am pleased to see that there is a solution for C++11. Regardless, no one has yet come up with an answer for C++98. So, even though I've accepted an answer, the question still stands.

Let us assume you have a function within a namespace:

namespace Math
{
  int Sum(<params>);
}

How do you implement this function Math::Sum such that the caller can call it with any number of arguments yet the caller doesn't need to pass the number of arguments too. The caller also needs to still have to fully qualify it at the call site. Example: Math::Sum(2, 4, 6, 8, 10, 12)

Upvotes: 2

Views: 207

Answers (2)

Andy Prowl
Andy Prowl

Reputation: 126412

Here is one generic way that works, in C++11, with any type supporting the additive operator (operator +):

#include <iostream>
#include <string>

template<typename T, typename U>
auto Sum(T&& t, U&& u) -> decltype(t + u)
{
    return (t + u);
}

template<typename T, typename... Ts>
auto Sum(T&& t, Ts&&... ts) -> decltype(
    t + Sum(std::forward<Ts>(ts)...)
    )
{
    return t + Sum(std::forward<Ts>(ts)...);
}

int main()
{
    std::cout << Sum(1, 2, 3) << std::endl;
    std::cout << Sum(1.0, 2.0, 3.0) << std::endl;
    std::cout << Sum(std::string("Hello "), std::string("World!")) << std::endl;
}

Upvotes: 7

Jonathan Wakely
Jonathan Wakely

Reputation: 171253

The approach used by std::min and std::max in C++11 is to take an initializer_list

int Sum(std::initializer_list<int>);

This is suitable when all the arguments should be the same type. You would call it as Sum({ 1, 2, 3, 4})

Upvotes: 5

Related Questions