使用可变参数提取函数

时间:2012-05-25 20:50:53

标签: c++ visual-c++

鉴于我有这个功能:

void A::IAmCool(int x, ...)
{
        va_list args; 
        va_start (args, x);   
        va_end (args);
}

如何将var-args从一个函数传递到另一个函数?我正在寻找这样的东西:

void A::extractedFunction() /* this doesn't work */
{
        va_list args; 
        va_start (args, ?????);   
        va_end (args);
}

void A::IAmCool(int x, ...)
{
        extractedFunction();
}

这甚至可能吗?我试过使函数内联但不起作用。

2 个答案:

答案 0 :(得分:1)

通常的模式是使用valist实现主要的主力函数,并且可变函数仅作为“装饰”。然后,您可以直接从第三方呼叫站点使用main功能。例如:

#include <cstdarg>

int vgizmo(int a, std::va_list ap)
{
    // main implementation here!
}

int gizmo(int a, ...)  // interface function
{
    std::va_list ap;
    va_start(ap, a);
    int r = vgizmo(a, ap);
    va_end(ap);
    return r;
}

void some_other_stuff(bool q, char const * fmt, ...)
{
    std::va_list ap;
    va_start(ap, fmt);

    // ...

    int b = vgizmo(x, ap);   // third parties use vgizmo directly

    // ...

    va_end(ap);
}

答案 1 :(得分:0)

在类C语言(C,C ++,Objective-C等)中,您无法直接传递可变参数。但是,您可能(如果您正在开发外部库,或者您只是想为逆向工程师的工作提供便利),请提供您的函数的非变量版本,并使可变参数只包装​​它,以便你可以根据需要向你的函数传递尽可能多的参数 - 使用va_list。例如:

// variadic function
void variadic_func(int nargs, ...)
{
    // just wrap the non-variadic one
    va_list args;
    va_start(args, nargs);
    non_variadic_func(nargs, args);
    va_end(args);
}

// non-variadic function
void non_variadic_func(int nargs, va_list args)
{
    // do what you want with `args'
}

// you can pass down varargs like this:
void outmost_caller_func(int nargs, ...)
{
    // since you can't pass down the `...', you create a va_list argument list
    va_list args;
    va_start(args, nargs);
    // and call the non-variadic version of your function, just like the wrapper
    // would do (anyway, the wrapper is only for convenience...)
    non_variadic_func(nargs, args);
    va_end(args);
}