4

I am trying to implement a variadic function. I searched the web and ended up finding out that most examples handle only one type of arguments (for example calculating average of many integers). Im my case the argument type is not fixed. It can either involve char*, int or both at the same time. Here is the code i ended up with :

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.      */

Now this would work okay if i only had to deal with integers but as you see i have a char* c variable in comments which i would like to use in case the argument is a char*.

So the question is, how do I handle the returned value of va_arg without knowing if it is an int or a char* ?

5 Answers 5

10

since you're doing c++ there's no need to use untyped C-style variadic function.

you can simply define a chainable method like

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

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

then use like

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

variant with templated insert operation commonly used for building strings.

cheers & hth.,

Sign up to request clarification or add additional context in comments.

2 Comments

Are we missing some return *this?
While this is neat, the operator<< version seems more common, maybe add them? :)
3

So the question is, how do I handle the returned value of va_arg without knowing if it is an int or a char* ?

You can't. There is absolutely no way to determine the type of a variadic argument. You have to specify it somewhere else. That's why functions like printf require you to give the type of the arguments in the format string:

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

1 Comment

yup good point! :P I ended up doing it by expecting correct input. Meaning that i assume that the order of the args is correct. I might try to work on checking it if i have the time :)
2

You need some way of knowing. Consider how printf solves this, with a format string. It's not the only possible approach, but it's a well-known one.

Comments

0

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

In some other cases, for example printf, the number and types of arguments are figured out from a format string. In both cases, this depends on the programmer to actually supply the correct information.

So, to handle multiple types, the insertInto() need a concept like format string.

Comments

0

You can make the processing conditional on the dummy parameter. I have routines that take an "action" argument and treats the arguments differently based on the action

For example:

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;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.