2011-09-23 11 views
5

Tengo una función variad D-style foo(format, ...), que es un contenedor alrededor de writefln. Me gustaría hacer algo como esto:Pasando argumentos variados en una función a otra función en D

foo(format, <...>) { 
    //... 
    writefln(format, ...); 
} 

Esencialmente, pasando del parámetro (s) de puntos suspensivos para writefln. Entiendo que esto no es fácil/posible en C/C++, pero ¿hay alguna manera de lograr esto en D?

+0

Gracias a todos, resulta que las plantillas resolvieron el problema de manera muy limpia y elegante. Bonificación adicional: no causa ninguna asignación de memoria, por lo que se puede invocar desde destructores (es una función de un módulo de registro). –

Respuesta

4

Esto lo hará por usted:

import std.stdio; 
void customWrite(Args...)(string format, Args args) 
{ 
    writefln(format, args); 
} 
3

Si desea plantillas, puede hacerlo de esta manera:

auto bar(T...)(T args) { ... } 

auto foo(T...)(T args) 
{ 
    return bar!T(args); 
} 

pero si quieres tiempo de ejecución argumentos variadic, entonces usted tiene que hacer lo que C no: Paso de _argptr a la "v -versión "de su función, ej. vprintf.

+0

Puede ser 'bar (args)'. No deberías necesitar el '! T'. –

+1

@JonathanMDavis: Sí, me doy cuenta de eso. Pero siempre lo escribo explícitamente cuando llamo a un genérico de otro porque a menudo hace que los errores de compilación sean más fáciles de encontrar.(En lugar de decir "No puedo encontrar una coincidencia", en realidad te dice lo que no podría coincidir). – Mehrdad

+0

@Mehrdad: ¡una técnica digna de mención! – vines

4

me había olvidado que ese tipo de variadics incluso existido en D. No creo que TDPL incluso les menciona. Creo que lo que hace un total de 4 tipos diferentes de variadics en D.

  1. C variadics

    extern(C) void func(string format, ...) {...} 
    
  2. D variadics con TypeInfo

    void func(string format, ...) {...} 
    
  3. variadics homogéneos utilizando matrices

    void func(string format, string[] args...) {...} 
    
  4. variadics heterogéneos utilizando la plantilla variadics

    void func(T...)(string format, args) {...} 
    

Creo que TDPL realidad sólo habla de # 3 y # 4, y los que son todo lo que normalmente uso, por lo que tendría que ir a cavar a averiguar cómo pasar argumentos usando # 2. Espero que sea similar a cómo lo haces en C con el n. ° 1, pero no sé.

Sin embargo, es fácil con # 3 y # 4. En ambos casos, simplemente pase args a la función que desee pasar. Y ambos permiten indexar y dividir (por ejemplo, args[1] y args[1 .. $]) y tener una propiedad length. Por lo tanto, son fáciles de usar, y en su mayor parte, son la mejor manera de hacerlo. Las únicas excepciones que puedo pensar son si llamas a una función C existente (en cuyo caso, usas # 1) o si necesitas plantillas heterogéneas y no puedes permitirte el aumento en el tamaño binario que crean las plantillas (en las cuales caso de que use el n. ° 2), lo que realmente debería ser solo un problema en entornos integrados. En general, # 3 y # 4 y simplemente mejores soluciones.

+1

Mira un poco más abajo http://www.d-programming-language.org/function.html#variadic: # 3 también funciona con las clases. – BCS

Cuestiones relacionadas