Manejo de plantillas variadas en c ++ 11

Recientemente comencé a usar C++ 11 y leí un tutorial sobre plantillas variádicas. He entendido que podemos definir una plantilla variádica como esta

// example class that uses variadic template
template<typename ...Args> struct mtuple;

Pero, ¿cómo puedo manejar los argumentos de plantilla del mtuple clase (es decir, cómo sería el get<int>(mtuple_obj) ¿parece?)?

preguntado el 03 de mayo de 12 a las 19:05

La magia de plantillas Variadic es realmente mágica, tienes que experimentar con ella, así como mirar muchos ejemplos de código diferentes para ver qué y por qué está pasando allí. Aquí está mi intento de escribir mi propia clase Tuple (aunque no mires Tie() ;RE), como uno de esos ejemplos de código, también hay muchos aquí, en SO: explore plantillas-variadas y tratar de entenderlos. -

un par de preguntas relacionadas interesantes: stackoverflow.com/a/7868427/170521 y stackoverflow.com/q/7870498/170521 -

2 Respuestas

Lo que get<1>(t) parece dependerá de la implementación de mtuple. Una implementación típica hereda recursivamente de un tipo que contiene cada argumento, por lo que mtuple<A,B,C> hereda de TupleHead<A> (que tiene un miembro de tipo A) y también hereda de TupleTail<B,C>. TupleTail<B,C> hereda de TupleHead<B> (que tiene un miembro de tipo B) y TupleTail<C>. TupleTail<C> hereda de TupleHead<C> (que tiene un miembro de tipo C.)

Ahora, si le da a cada clase base un parámetro entero también:

mtuple<A,B,C> hereda de TupleHead<0,A> y TupleTail<1,B,C>

TupleTail<1,B,C> hereda de TupleHead<1,B> y TupleTail<2,C>

TupleTail<2,C> hereda de TupleHead<2,C>

Ahora es relativamente simple escribir get<1>, Debido a que el mtuple tiene una sola clase base única de tipo TupleHead<1,B> que se puede obtener mediante un upcast, luego devolver el B miembro de esa clase base.

[Editar: get<1>(m) necesita saber el tipo B que corresponde al elemento tupla con índice 1, para eso usas algo como std::tuple_element que también se basa en la jerarquía de herencia recursiva descrita anteriormente y utiliza la especialización parcial para obtener el TupleHead<1,T> clase base con índice 1, luego determina el parámetro T en esa especialización parcial, que da B en mi ejemplo.]

Muchas de las técnicas que se utilizan con las plantillas variádicas son técnicas de programación funcional, como operar en el primer elemento del paquete de parámetros de la plantilla y luego hacer lo mismo recursivamente en el resto del paquete, hasta que haya procesado todos los elementos. No hay muchas cosas que pueda hacer directamente con un paquete de parámetros de plantilla excepto contar su tamaño (con sizeof...) o crear una instancia de otra plantilla con ella, por lo que el enfoque habitual es crear una instancia de otra plantilla que separe el paquete Args dentro ArgHead, ArgsTail... y procesa la cabeza, luego recursivamente hacer lo mismo para ArgsTail

contestado el 04 de mayo de 12 a las 16:05

No existe un mecanismo simple para iterar sobre los valores de una plantilla variádica. Pero esto se puede hacer recursivamente. Aquí hay un ejemplo:

template<typename T, typename... Args>
void print_values(const char *s, T value, Args... args)
{
    while (*s) {
        if (*s == '%' && *(++s) != '%') {
            std::cout << value;
            ++s;
            print_values(s, args...);
            return;
        }
        cout << *(s++);
    }
}

Entonces, si llamo print_values("%d %d %d", 1, 2, 3) Obtengo este árbol de recursión:

print_values("%d %d %d", 1, 2, 3) // value -> 1, args... -> 2,3
print_values("%d %d", 2, 3) // value -> 2, args... -> 3
print_values("%d", 3) // value -> 3, args... -> NULL
print_values("") // value -> NULL, args... -> NULL

llamo recursivamente print_values() incluso cuando *s == 0 para detectar argumentos adicionales

Fuente: http://en.wikipedia.org/wiki/Variadic_templates

contestado el 04 de mayo de 12 a las 12:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.