No estoy seguro si esto funciona para todos los compiladores, pero me ha funcionado hasta ahora.
void inner_func(int &i)
{
va_list vars;
va_start(vars, i);
int j = va_arg(vars);
va_end(vars); // Generally useless, but should be included.
}
void func(int i, ...)
{
inner_func(i);
}
Puede agregar el ... a inner_func() si lo desea, pero no lo necesita. Funciona porque va_start usa la dirección de la variable dada como punto de inicio. En este caso, le estamos dando una referencia a una variable en func(). Entonces usa esa dirección y lee las variables después de eso en la pila. La función inner_func() lee de la dirección de pila de func(). Por lo tanto, solo funciona si ambas funciones usan el mismo segmento de pila.
Las macros va_start y va_arg generalmente funcionarán si les das cualquier var como punto de partida. Entonces, si lo desea, puede pasar punteros a otras funciones y usarlas también. Puede crear sus propias macros con la suficiente facilidad. Todas las macros son las direcciones de memoria de tipo de letra. Sin embargo, hacerlos funcionar para todos los compiladores y convenciones de llamadas es molesto. Por lo general, es más fácil usar los que vienen con el compilador.
Tu ejemplo me parece un poco raro, ya que pasas fmt a format_string() y a fprintf(). ¿Debería format_string() devolver una nueva cadena de alguna manera? –
El ejemplo no tiene sentido. Fue solo para mostrar el contorno del código. –
"debe ser googleado": no estoy de acuerdo. Google tiene mucho ruido (información poco clara, a menudo confusa). ¡Tener un buen (votado, respuesta aceptada) en stackoverflow realmente ayuda! – Ansgar