Max Frai
Max Frai

Reputation: 64266

Process va_args in c++

I have a function A(...) and B(...). Now I have to call B inside A, any methods to pass that ... from A into B? Pseudocode:

void A(...)
{
   // Some operators
   B(...); // Instead of ... I need to pass A's args
}

p.s. I know this could be done using macros but what about functions.

Upvotes: 6

Views: 1216

Answers (3)

Riccardo Tramma
Riccardo Tramma

Reputation: 593

You need to slightly change the signature of your methods. I assume you want to do something like this:

void B(int numParams, va_list parameters)
{
    // Your code here. Example:
    for (int i=0; i<numParams; i++)
    {
        // Do something using va_arg to retrieve your parameters
    }
}

void A(int numParams, ...)
{
    va_list parameters;
    va_start(parameters, numParams);
    B(numParams, parameters);
    va_end(parameters);
}

Upvotes: 1

Matthew Walton
Matthew Walton

Reputation: 9959

Unfortunately you can't take a va-list and pass it to a function accepting a variable argument list. There is no syntax allowing you to expand the va_args structure back into parameters.

You can pass it as a va_list in a single parameter, so one solution would be to define the function that does the work as taking a va_list. Then you can define another function wrapping it taking an argument list which can then pass a va_list to the core function and pass the return value back. You see this kind of pattern in the C standard library with printf() and vprintf() and similar pairings.

Upvotes: 2

kennytm
kennytm

Reputation: 523264

You can't forward va_args. You can only forward va_list.

void vB(int first, va_list ap)
{
   // do stuff with ap.
}

void B(int first, ...)
{
   va_list ap;
   va_start(ap, first);
   vB(first, ap);
   va_end(ap);
}

void A(int something_else, int first, ...)
{
   va_list ap;
   va_start(ap, first);
   vB(first, ap);       // <-- call vB instead of B.
   va_end(ap);
}

(This is also why functions like vprintf exists.)


If you are using C++11, you could do this with variadic templates with perfect forwarding:

template <typename... T>
void A(T&&... args)
{
    B(std::forward<T>(args)...);
}

Upvotes: 7

Related Questions