1

I have a function that takes 3 arguments. a vector of other functions, a void*, and an arbitrary list of arguments. The function is designed to pass in it's void* and arbitrary list of arguments to each function in the list, which the functions will handle themselves. here is an example of what I want:

typedef void (*fptr)(const void* userdata, ...);

void execute_all(vector<fptr> funcs, void* userdata, ...){
    for (int i = 0;i<funcs.size();i++){
        fptr func = funcs[i];
        //execute func with userdata and ... from above.
        //like (*func)(userdata, ...); which obviously doesnt work
    }
}

I need to know how to forward all arguments into each function. Dont worry about ensuring compatibility. I handle that elsewhere.

Thanks

ewok
  • 20,148
  • 51
  • 149
  • 254
  • 1
    Have you considered _variadic templates_ feature of C++11? – Mr.C64 Oct 03 '12 at 15:55
  • 1
    @user1629821 I don't believe that I can assume c++11 is installed on the target machine – ewok Oct 03 '12 at 15:56
  • do you mean that each of the functions is executed with the same parameters? – Zdeslav Vojkovic Oct 03 '12 at 15:58
  • 6
    there is no such thing as C++11 installed. You build an executable which has no notion of C++ version. Unless by 'target' you mean development machine. – Zdeslav Vojkovic Oct 03 '12 at 15:59
  • @ZdeslavVojkovic Ah. well in that case, variadic templates might be the way to go. I'll have to look into it, unless you can give me a simple example of how to do it here – ewok Oct 03 '12 at 16:47
  • There are already many answers about variadic templates, so I wouldn't like to repeat them: http://stackoverflow.com/search?q=variadic+templates – Zdeslav Vojkovic Oct 03 '12 at 17:51

3 Answers3

3

You can't directly pass down variadic arguments from a variadic function to another variadic function. However, you can make the called (inner) function accept a va_list, then pass that list around:

#include <cstdarg>

void callee(void *first, va_list args);

void caller(void *first, ...)
{
    va_list args;
    va_start(args, first);
    callee(first, args);
    va_end(args);
}
2

There is no way that you can efficiently move arguments of a variadic function to another function, but you can move your stack to another function, so it can peek arguments from stack itself. Ansi C introduce va_list just for this purpose. You can have following code:

void fwd_function( int argCount, ... ) {
    va_list vargs;
    va_start( vargs, argCount );
    impl_function( argCount, vargs );
    va_end( vargs );
}
void impl_function( int argCount, va_list args ) {
    int i;
    for( i = 0; i < argCount; i++ ) {
        int arg = va_arg( args, int );
    }
}
BigBoss
  • 6,904
  • 2
  • 23
  • 38
1

You should use a variadic templates and perfect forwarding in C++11.

If you don't have that, AFAIK there's a Boost library that will mimick those for you.

Tony The Lion
  • 61,704
  • 67
  • 242
  • 415