Continuando con my journey into the world of variadic templates, me encontré con otro problema.especialización de plantilla parcial con varios paquetes de parámetros de plantilla
Suponiendo que la siguiente clase de plantilla:
template < typename T >
struct foo
{
//default implementation
};
es posible especializarse en parte por instancias plantilla variadic como este:
template < template < typename ... > class T, typename ...Args >
struct foo< T<Args...> >
{
//specialized implementation
};
Con esto, foo<int>
corresponderá a la implementación predeterminada y foo< std::tuple< int, char > >
a la implementación especializada.
Sin embargo, las cosas se vuelven más complicadas cuando se usan varios parámetros de plantilla. Por ejemplo, si tenemos la siguiente clase de plantilla
template < typename T, typename U >
struct bar {};
y queremos especializar parcialmente, tal como lo hicimos para foo
, no podemos hacer
template < template < typename ... > class T, typename ...TArgs,
template < typename ... > class U, typename ...UArgs >
struct bar< T<TArgs...>, U<UArgs...> > {};
//This would correspond to the specialized version with
//T=std::tuple,
//TArgs=int,char
//U=std::tuple,
//UArgs=float
bar< std::tuple< int, char >, std::tuple<float> > b;
De hecho, si estoy en lo correcto, sólo nos queda tiene un paquete de parámetros de plantilla y debe colocarse al final de la lista de parámetros. Entiendo por qué esto es obligatorio en las declaraciones de plantillas, pero para cierta especialización parcial de plantillas (como en el ejemplo anterior), esto no debería ser un problema.
¿Es posible lograr la especialización de plantilla parcial con múltiples paquetes de parámetros de plantilla?
Editar: Ahora me siento tonta ... el código que di arriba compila perfectamente (al menos con gcc 4.5). El error de compilación que tuve no se debió a múltiples paquetes de parámetros, sino a su uso como parámetros de funciones miembro. En la especialización parcial de bar
, traté de definir una función miembro que tiene en cuenta tanto TArgs
y UArgs
parámetros:
template < template < typename ... > class T, typename ...TArgs,
template < typename ... > class U, typename ...UArgs >
struct bar< T<TArgs...>, U<UArgs...> >
{
void method(TArgs... targs, UArgs... uargs) //compile error here
{
}
};
En la declaración de la función miembro, gcc me da el error
parámetros paquetes deben estar al final de la lista de parámetros.
Por lo que puedo decir, el compilador debería ser capaz de definir la función de miembro correcta para una instancia de plantilla determinada, p. bar< std::tuple< int, char >, std::tuple<float> >
debe contener una función de miembro void method(int, char, float)
. ¿Estoy haciendo algo mal? ¿O estoy tratando de hacer algo que no es posible? Si es así, ¿hay una buena razón por la cual esto no es posible?
Limpio, no sabía que pudiera especializar/especificar (parte de) los elementos de una lista de plantillas como las propias plantillas. – JAB