2012-05-25 2 views
1

Учитывая У меня есть функция:экстракт функции с переменными аргументами

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

Как передать VAR-арг от одной функции к другой? Я ищу что-то вроде этого:

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

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

Возможно ли это? Я попытался сделать функцию встроенной, но это не сработает.

+2

Я не знаю, что здесь означает «выдержка». Вроде, вообще. – djechlin

+0

@djechlin: Я собираюсь угадать, это ссылка на рефакторинг в стиле Eclipse. –

+0

это может помочь: http://en.wikipedia.org/wiki/Code_refactoring –

ответ

1

Обычная картина для реализации вашей основная функции лошадки принимая valist, и VARIADIC функции только как «украшение». Затем вы можете использовать основную функцию непосредственно со сторонних сайтов вызовов. Пример:

#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); 
} 
+0

См. 'Vprintf()' для широко распространенного примера этого подхода ... на linux, просто 'man vprintf'. И важно отметить, что, несмотря на то, что он выглядит как вызов функции «пошаговая функция», 'va_arg()' является макросом, который изменяет 'va_list'. Другими словами, вы не можете передать один и тот же 'va_list' в две разные функции без' va_end() 'и другой' va_start() 'между ними. Кроме того, персональная страница linux 'man stdarg' довольно хороша. –

+0

@BrianMcFarland: вы можете использовать 'va_copy' для создания нескольких копий данного валиста. –

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); 
} 
Смежные вопросы