Search code examples
c++overloadingvariadic-functions

How to overload a function taking variable number of arguments


I need to distinguish (overload) between two functions - one takes a single const char* argument and the other takes at least two arguments - a const char* followed by one or more arguments. i.e. basically:

void f(const char *str);
void f(const char *format, ...)

I want the first version to be called for f("hello") and the second version for f("hello %d", 10). The above overload won't work because the compiler finds f("hello") ambiguous.

So I tried this:

void f(const char *str);

template<typename T>
void f(const char *str, T tt, ...);

This makes the overload resolution work correctly. But I end up with another problem. The second function is supposed to forward the arguments for printf-style usage. So I have something like:

template <typename T>
void f ( const char *format, T tt, ... )
{
    (T)tt;
    va_list varlist;
    va_start(varlist, format);
    vprintf(format, varlist);
    va_end(varlist);
}

Now the second argument tt is no longer part of the variable argument list and calling va_start() with format does not seem to work.

Is there any way to achieve what I want?


Solution

  • If you use a vararg template you can accomplish what you want:

    #include <iostream>
    
    void f(const char* str)
    {
        std::cout << "single arg: " << str << "\n";
    }
    
    template <typename ...T>
    void f(const char *format, T... args)
    {
        printf(format, args...);
    }
    
    int main()
    {
        f("hello");
        f("formatted %d", 10);
    }