Ответ, который был признан бесполезным
Вопрос не был правильно объяснен. Этот ответ не ответил на вопрос, который имел в виду спрашивающий, но ответил на вопрос, который, казалось, был задан. Между намерением и реальностью был разрыв.
#define boo(fmt, ...) SomethingToDo(fmt, __VA_ARGS__) // semi-colon removed!
void foo(PCSTR fmt, ...)
{
// some other codes
// I want to call boo with VarArgs.
if (somecondition)
boo(fmt, arg1, arg2);
if (anothercondition)
boo("%x %y %z", e1, e2, e3);
if (yetanothercondition)
boo("&T99 P37 T22 9%X ZZQ", x1, y2, z3, a4, b9, c7, q99);
}
Помимо всего остального, вы вызываете функцию или макрос с аргументами, необходимыми для выполнения вашей работы. Поскольку вы не указываете, какой формат должен быть отформатирован, я подготовил строки форматирования для себя - они, вероятно, не очень удобны, но кто знает.
В любом случае, ключевым моментом является то, что вы можете вызвать boo()
макрос с различными списками аргументов, и эти аргументы будут переданы SomethingToDo()
.
Ответ, который был сочтен более полезным
Учитывая уточнение в комментарии, то:
#define boo(fmt, ...) SomethingToDo(fmt, __VA_ARGS__)
void foo(PCSTR fmt, ...)
{
va_list args;
// I want to call boo with VarArgs.
if (somecondition)
{
va_start(args, fmt);
boo(fmt, args);
va_end(args);
}
}
Однако, чтобы это работало, базовая функция должна знать, как обрабатывать va_list
. Это означает, что вы обычно получаете следующий код со структурой, подобной следующей:
void vSomethingToDo(const char *fmt, va_list args)
{
...code using vfprintf() or whatever...
}
void SomethingToDo(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vSomethingToDo(fmt, args);
va_end(args);
}
#define vboo(fmt, args) vSomethingToDo(fmt, args)
#define boo(fmt, ...) SomethingToDo(fmt, __VA_ARGS__)
void foo(PCSTR fmt, ...)
{
...other code...
if (somecondition)
{
va_list args;
va_start(args, fmt);
vboo(fmt, args);
va_end(args);
}
}
Это «стандартный шаблон» для кода, который использует переменные аргументы. Вы можете видеть это в стандартном C с: printf()
и vprintf()
; snprintf()
и vsnprintf()
; fprintf()
и vfprintf()
; и так далее. У одной версии функции есть многоточие в списке аргументов; другая версия имеет префикс с буквой «v» и вместо многоточия принимает «va_list». Код многоточия стандартизирован в четыре или пять строк - более или менее, как показано; он создает и инициализирует va_list с помощью va_start, вызывает функцию v и возвращает результат после выполнения va_end.