2012-02-17 9 views
6

Tengo una función A(...) y B(...). Ahora tengo que llamar a B dentro de A, cualquier método para pasar ese ... de A al B? Pseudocódigo:Proceso va_args en C++

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

p.s. Sé que esto podría hacerse usando macros, pero ¿qué pasa con las funciones?

Respuesta

7

No puede reenviar va_args. Solo puede reenviar 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); 
} 

(. Esto es también por qué existe funciones como vprintf)


Si está utilizando C++ 11, se puede hacer esto con las plantillas variadic con perfecta reenvío:

template <typename... T> 
void A(T&&... args) 
{ 
    B(std::forward<T>(args)...); 
} 
2

Desafortunadamente no puede tomar un va-list y pasarlo a una función que acepte una lista de argumentos variables. No hay sintaxis que le permita expandir la estructura va_args a parámetros.

Puede pasarlo como va_list en un solo parámetro, por lo que una solución sería definir la función que realiza el trabajo tomando va_list. Luego puede definir otra función envolviéndola tomando una lista de argumentos que luego puede pasar un va_list a la función central y devolver el valor de retorno. Verá este tipo de patrón en la biblioteca estándar C con printf() y vprintf() y emparejamientos similares.

1

Necesita cambiar ligeramente la firma de sus métodos. Supongo que quiere hacer algo como esto:

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); 
} 
Cuestiones relacionadas