c ++ varargs / variadic функция с двумя типами аргументов - PullRequest
3 голосов
/ 05 февраля 2011

Я пытаюсь реализовать переменную функцию. Я искал в Интернете и в итоге обнаружил, что большинство примеров обрабатывают только один тип аргументов (например, вычисление среднего числа многих целых). В моем случае тип аргумента не является фиксированным. Он может включать char *, int или оба одновременно. Вот код, с которым я закончил:

void insertInto(int dummy, ... ) {
   int i = dummy;
   va_list marker;
   va_start( marker, dummy );     /* Initialize variable arguments. */
   while( i != -1 ) {
      cout<<"arg "<<i<<endl;
             /* Do something with i or c here */
      i = va_arg( marker, int);
      //c = va_arg( marker, char*);
   }
   va_end( marker );              /* Reset variable arguments.      */

Теперь это будет работать нормально, если бы мне приходилось иметь дело только с целыми числами, но, как вы видите, у меня есть переменная char * c в комментариях, которую я хотел бы использовать в случае, если аргумент является char *.

Итак, вопрос в том, как мне обработать возвращаемое значение va_arg, не зная, является ли оно int или char *?

Ответы [ 5 ]

11 голосов
/ 05 февраля 2011

, поскольку вы работаете с C ++, нет необходимости использовать нетипизированную переменную в стиле C.

Вы можете просто определить цепной метод как

  class Inserter
  {
  public:
      Inserter& operator()( char const* s )
      {
          cout << s << endl;
          return *this;
      }

      Inserter& operator()( int i )
      {
          cout << i << endl;
          return *this;
      }
  };

затем используйте как

Inserter()( "blah" )( 42 )( "duh" )

вариант с шаблонной операцией вставки, обычно используемой для построения строк.

ура и hth.,

3 голосов
/ 05 февраля 2011

Итак, вопрос в том, как мне обработать возвращаемое значение va_arg, не зная, является ли оно int или char *?

Вы не можете.Нет абсолютно никакого способа определить тип вариационного аргумента.Вы должны указать это где-то еще.Вот почему функции типа printf требуют, чтобы вы указали тип аргументов в строке формата:

printf("%s %i\n", "Hello", 123);  // works
printf("%s %i\n", 123, "Hello");  // also valid (though most modern compiles will emit a warning), but will produce garbage or crash
2 голосов
/ 05 февраля 2011

Тебе нужен способ узнать.Посмотрите, как printf решает это со строкой формата.Это не единственный возможный подход, но он хорошо известен.

0 голосов
/ 05 февраля 2011

Вы можете сделать обработку условной по фиктивному параметру.У меня есть подпрограммы, которые принимают аргумент "action" и обрабатывают аргументы по-разному в зависимости от действия

Например:

int i; char *c;
switch(dummy) {
    case 1:
        i = va_arg(marker, int);
        // do something with i
        break;
    case 2:
        c = va_arg(market, char *);
        // do something with c
        break;
}
0 голосов
/ 05 февраля 2011

С http://en.wikipedia.org/wiki/Variadic_function#Variadic_functions_in_C.2C_Objective-C.2C_C.2B.2B.2C_and_D:

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

Таким образом, для работы с несколькими типами insertInto() требуется понятие типа строки формата.

...