How to pass pointers and process them using ellipsis ?
-
I understand the concept of using ellipsis to pass variable number of parameters to a function. However, the tutorial examples pass a simple values to demonstrate the workings of "list" . I like to pass a object / widget (pointer) parameter and process the passed parameter. For example equivalent to this: object -> add text (text ) Can that be done and if so can you post actual C++ code ? Am I actually trying to do similar as passing a function as a parameter ? My code call looks like this ellipsisFunction( 2, listWidget_1, lisTWidget_2) /* va_start example */ #include /* printf */ #include /* va_list, va_start, va_arg, va_end */ void PrintFloats (int n, ...) { int i; double val; printf ("Printing floats:"); va_list vl; va_start(vl,n); for (i=0;i
-
I understand the concept of using ellipsis to pass variable number of parameters to a function. However, the tutorial examples pass a simple values to demonstrate the workings of "list" . I like to pass a object / widget (pointer) parameter and process the passed parameter. For example equivalent to this: object -> add text (text ) Can that be done and if so can you post actual C++ code ? Am I actually trying to do similar as passing a function as a parameter ? My code call looks like this ellipsisFunction( 2, listWidget_1, lisTWidget_2) /* va_start example */ #include /* printf */ #include /* va_list, va_start, va_arg, va_end */ void PrintFloats (int n, ...) { int i; double val; printf ("Printing floats:"); va_list vl; va_start(vl,n); for (i=0;i
-
If you pass a list of random types (numbers, strings, objects), then your function needs some method of determining what each reference is. That is why
printf
(and its derivatives) requires a format string to identify the type of each parameter. -
I am aware that compiler by itself cannot determine the type of variable passed. What I am missing is - how iterating thru the list works .
I'm not sure exactly where you're stuck. But lets start with the example you gave in your original post:
void PrintFloats (int n, ...)
{
int i;
double val;
printf ("Printing floats:");
va_list vl;
va_start(vl,n);
for (i=0;iAssuming that you're stuck here, then you might complete this something like
for(i = 0; i < n; ++i) { val = va\_arg(vl, float); printf("%f ", val); } va\_end(vl); putchar('\\n');
In this case I'm assuming that the
int n
parameter tells the function how many float values to expect. Other options to tell a variadic function how many arguments to expect are to use some sort of format string, like printf() does, or you can use some sort of sentinel value for your function e.g.PrintFloats(1.1, 2.2, -15.2, nan(""));
In this case we have assumed that a NaN won't be part of the input string, so is a fair choice for a sentinel.
Keep Calm and Carry On
-
I am aware that compiler by itself cannot determine the type of variable passed. What I am missing is - how iterating thru the list works .
-
I'm not sure exactly where you're stuck. But lets start with the example you gave in your original post:
void PrintFloats (int n, ...)
{
int i;
double val;
printf ("Printing floats:");
va_list vl;
va_start(vl,n);
for (i=0;iAssuming that you're stuck here, then you might complete this something like
for(i = 0; i < n; ++i) { val = va\_arg(vl, float); printf("%f ", val); } va\_end(vl); putchar('\\n');
In this case I'm assuming that the
int n
parameter tells the function how many float values to expect. Other options to tell a variadic function how many arguments to expect are to use some sort of format string, like printf() does, or you can use some sort of sentinel value for your function e.g.PrintFloats(1.1, 2.2, -15.2, nan(""));
In this case we have assumed that a NaN won't be part of the input string, so is a fair choice for a sentinel.
Keep Calm and Carry On
OK, let's move on. The variadic function contains the passed parameters count. The va_arg gets the parameter TYPE and according to the doc it has to match some specification. ( I gather the type can be also passed...but that is way over my head for now ) If I desire to pass type which does not meet this spec - all bets are off. I am trying to pass a pointer to an object. Does that sounds reasonable ? The example I used has type float for(i = 0; i < n; ++i) { val = va_arg(vl, float); replacing float with an object printf("%f ", val); } va_end(vl); putchar('\n');
-
OK, let's move on. The variadic function contains the passed parameters count. The va_arg gets the parameter TYPE and according to the doc it has to match some specification. ( I gather the type can be also passed...but that is way over my head for now ) If I desire to pass type which does not meet this spec - all bets are off. I am trying to pass a pointer to an object. Does that sounds reasonable ? The example I used has type float for(i = 0; i < n; ++i) { val = va_arg(vl, float); replacing float with an object printf("%f ", val); } va_end(vl); putchar('\n');
It's pretty straight forward, really. When you use the
va_arg
macro, the second argument is the received objects type. So, to receive a pointer to a type, you useva_arg(args, _Obj_*)
where Obj is some object type - e.g. class, int, double, struct, etc. Here's a short working example:#include
#includestruct S {
int data;
S(int d) : data(d) {}
};void f(size_t n, ...)
{
va_list args;
va_start(args, n);
for(size_t i = 0; i < n; ++i) {
S* ptr = va_arg(args, S*);
std::cout << ptr->data << '\n';
}
}int main()
{
S item1(1);
S item2(2);
S item3(3);f(3, &item1, &item2, &item3);
}
Keep Calm and Carry On