2012-06-17 19 views
6

Si esto es posible, se puede indexar en un paquete de parámetros de plantilla variadic sin recurrencia. Sin embargo, GCC es refusing to pick up my partial specialization aquí:¿Puedo especializar parcialmente una plantilla con un patrón como foo <T ..., int, U ...>?

template <int I, typename List> 
struct element_impl; 

template <typename... TL, int... IL, typename T, int I, typename... TR, int... IR> 
struct element_impl<I, typelist<pair<TL,IL>..., pair<T,I>, pair<TR,IR>...>> { 
    typedef T type; 
}; 

prog.cpp: In instantiation of ' element<0, typelist<int, double, char, float, long int> > ':
prog.cpp:52:34: instantiated from here
prog.cpp:47:79: error: invalid use of incomplete type ' struct element_impl<0, typelist<pair<int, 0>, pair<double, 1>, pair<char, 2>, pair<float, 3>, pair<long int, 4> > '

GCC está libre de errores, o estoy haciendo caso omiso de alguna limitación de plantillas variadic?

+0

Con [este código simple] (http://ideone.com/CrNSc), GCC dice: 'error: el paquete de parámetros 'T' debe estar al final de la lista de parámetros de la plantilla'. Así que tiendo a pensar que es una limitación de lenguaje. – Nawaz

+0

@Nawaz Eso no es para nada lo mismo. –

+0

No es "exactamente" igual, pero el mensaje de error es bastante claro: el paquete de parámetros * debe estar * al final de la lista de parámetros de la plantilla. GCC repite el mismo mensaje aquí: http://ideone.com/2Rifn – Nawaz

Respuesta

5

La especificación dice en 14.8.2.5p9

If P has a form that contains <T> or <i> , then each argument Pi of the respective template argument list P is compared with the corresponding argument Ai of the corresponding template argument list of A . If the template argument list of P contains a pack expansion that is not the last template argument, the entire template argument list is a non-deduced context.

Su typelist<T> lamentablemente coincide con el patrón.

+0

¿Puedes explicar el texto del estándar en palabras simples, posiblemente con uno o dos ejemplos? – Nawaz

+0

@Nawaz @RMartinho mostró un excelente ejemplo de esta regla, posiblemente mejor que cualquier otra, podría ser '' significa "lista de argumentos de la plantilla que contiene un parámetro de tipo (paquete)" y "" significa "lista de argumentos de la plantilla que contiene un parámetro no de tipo (paquete)". –

2

AFAICT, las reglas para la coincidencia de especializaciones parciales son las mismas que las reglas de deducción de los parámetros de la función. Y §14.8.2.1/1 dice lo siguiente:

For a function parameter pack that occurs at the end of the parameter-declaration-list, the type A of each remaining argument of the call is compared with the type P of the declarator-id of the function parameter pack. Each comparison deduces template arguments for subsequent positions in the template parameter packs expanded by the function parameter pack. For a function parameter pack that does not occur at the end of the parameter-declaration-list, the type of the parameter pack is a non-deduced context.

Así que los paquetes TL y IL no se puede deducir en este caso, y la especialización parcial no es captada.

Cuestiones relacionadas