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.
va_arg returns the value of the next argument in a varying-length argument list. The first argument, ap , is a work area of type va_list , which is used by the expansions of the various <stdarg. h> macros.
The C standard mandates that the only place the identifier __VA_ARGS__ can appear is in the replacement list of a variadic macro. It may not be used as a macro name, macro argument name, or within a different type of macro. It may also be forbidden in open text; the standard is ambiguous.
In the most usual stack-based situation, the va_list is merely a pointer to the arguments sitting on the stack, and va_arg increments the pointer, casts it and dereferences it to a value. Then va_start initialises that pointer by some simple arithmetic (and inside knowledge) and va_end does nothing.
Variable length argument is a feature that allows a function to receive any number of arguments. There are situations where we want a function to handle variable number of arguments according to requirement. 1) Sum of given numbers.
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)...);
}
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.
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With