Процесс va_args в C ++ - PullRequest
       2

Процесс va_args в C ++

6 голосов
/ 17 февраля 2012

У меня есть функции A(...) и B(...).Теперь мне нужно вызвать B внутри A, есть ли методы, чтобы передать это ... из A в B?Псевдокод:

void A(...)
{
   // Some operators
   B(...); // Instead of ... I need to pass A's args
}

ps Я знаю, что это можно сделать с помощью макросов, но как насчет функций.

Ответы [ 3 ]

7 голосов
/ 17 февраля 2012

Вы не можете пересылать va_args.Вы можете пересылать только 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);
}

(по этой же причине существуют такие функции, как vprintf.)


Если вы используете C ++ 11, вы можете сделать этос вариадическими шаблонами с идеальной пересылкой:

template <typename... T>
void A(T&&... args)
{
    B(std::forward<T>(args)...);
}
2 голосов
/ 17 февраля 2012

К сожалению, вы не можете взять va-list и передать его функции, принимающей список переменных аргументов. Нет синтаксиса, позволяющего развернуть структуру va_args обратно в параметры.

Вы можете передать его как va_list в одном параметре, поэтому одним из решений будет определение функции, выполняющей работу, как va_list. Затем вы можете определить другую функцию, заключив ее в список аргументов, который затем может передать va_list основной функции и вернуть возвращаемое значение. Вы видите этот тип паттерна в стандартной библиотеке C с printf() и vprintf() и подобными парами.

1 голос
/ 17 февраля 2012

Вам нужно немного изменить сигнатуру ваших методов. Я предполагаю, что вы хотите сделать что-то вроде этого:

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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...