Ya sé el stdarg.h manera de tener una función con la variable de argumentos en c++ como se discutió aquí por ejemplo.
También sé c++11 estándar ha variadic plantillas como se explica aquí.

Pero en ambos de dichos esquemas no sabemos (y que no podemos obligar a) argumento de tipos en tiempo de compilación afaik. Lo que estoy buscando es pasar la variable de argumentos de tipos conocidos a una función. Creo que esto puede ser hecho, porque he leído sobre él aquí:

Variadic plantillas, que también puede ser utilizado para crear las funciones que toman número variable de argumentos, son a menudo la mejor opción debido a que no se imponen restricciones sobre el tipo de los argumentos, no realizar integral y de punto flotante de promociones, y son de tipo seguro.

Es posible? Si sí, ¿cómo puedo hacer esto?

InformationsquelleAutor melmi | 2012-04-06

2 Comentarios

  1. 30

    Es directa para escribir una función con variadic plantillas, que aceptan un número arbitrario de argumentos. La única diferencia con el patrón general es que un tipo concreto, se utiliza como primer argumento (de la cabeza) – en lugar de un parámetro de plantilla. El siguiente ejemplo muestra una función foobar, que acepta un número arbitrario de las cadenas.

    //used for end of recursion - and for the empty arguments list
    void foobar() { }
    
    template <typename ...Tail>
    void foobar(const std::string& head, Tail&&... tail)
    {
        //do something with head
        std::cout << head << '\n';
        //call foobar recursively with remaining arguments
        foobar(std::forward<Tail>(tail)...);
    }
    
    foobar("Hello", "World", "...");

    Personalmente, yo prefiero usar std::initializer_list en lugar de variadic plantillas. Porque variadic plantillas son más complejos y requieren de experiencia adicional. Con std::initializer_list, podría tener este aspecto:

    void foobar(std::initializer_list<std::string> values)
    {
        for (auto& value : values) {
            //do something with value
            std::cout << value << '\n';
        }
    }
    
    foobar({ "Hello", "World", "...", });

    Por desgracia, el adicional de llaves son necesarios cuando se utiliza std::initializer_list con funciones regulares. Ellos no son necesarios para los constructores, si el nuevo inicializador se utiliza la sintaxis.

    Edición: Reescribió la respuesta de acuerdo a los comentarios. En particular, he cambiado el orden de las dos soluciones/ejemplos.

    • Creo que fue todo acerca de mi falta de comprensión. Yo sabía que de la segunda manera, pero siempre he pensado que no hay ningún control sobre el tipo de los parámetros. Esto no es cierto. debido a que la función toma un primer parámetro de un tipo conocido (string aquí), implícitamente se ven obligados a tener sus parámetros de ese tipo. Gracias.
    • Puede que desee mover el código del segundo cuadro primero. Es una muy buena solución para el problema, mientras que la initializer_list versión no. Yo iba a publicar un grande, complejo cosa con SFINAE y tal, pero esto es mucho más razonable.
    • usted puede evitar el uso de llaves si se mezcla tanto el std::initializer_list y la variadic plantilla de enfoque, mediante la creación de un variadic plantilla de envoltura alrededor de la std::initializer_list versión, como este: ver en coliru.
    • Usted puede hacer eso, pero se pierde un beneficio importante de std::initializer_list. No es posible el uso de llave de inicialización para el elemento, es decir, de las siguientes obras con std::initializer_list: foobar({{"foo", 1, 2}, {"bar", 2, 1}});.
    • De hecho, y todavía funciona incluso cuando el contenedor está disponible. El uso de esos cadena de constructores con el contenedor de plantilla tendría que explícitamente el nombre del tipo std::string. Se ilustra en la este otro coliru.
  2. 2

    Si los parámetros variables son todos de un mismo tipo, puede cambiar la función de la firma para que tome un array de esos tipos en lugar de utilizar el ‘…’.

    • Un conjunto de un tipo de necesidades de la iteración, mientras que el uso de variadic funciones proporciona un tiempo de compilación en línea de mecanismo. Se puede decir que el bucle en una matriz no es por lo que el tiempo conuming, sino que la consideran en otro de los múltiples bucles grandes.

Dejar respuesta

Please enter your comment!
Please enter your name here