2010-01-13 22 views
7

Estaba tratando de resolver un problema, pero encontré una solución diferente. Sin embargo por curiosidad gustaría saber si la siguiente es posible:C++ plantilla especializada hereda de la versión no especializada

template<class> struct S; 
template< > struct S<Foo> : struct<Foo> {}; 

me gustaría ser capaz de heredar la estructura no especializado desde especializado struct.the ejemplo anterior no funciona porque la estructura heredada es la especializada, lo que lleva a la recursión infinita.

Una posible solución fue agregar un segundo parámetro de plantilla, por ejemplo bool especializado, de manera que el valor predeterminado sea falso y la plantilla especializada tenga ese parámetro verdadero. Sin embargo, eso hace las cosas un poco complicadas ya que la instanciación necesita especificar un parámetro adicional.

¿Hay alguna otra forma de implementar lo anterior?

el problema original era implementar una matriz de matrices, donde la matriz misma puede tener operadores adicionales, dependiendo de si las matrices constituyentes tienen esos operadores. Espero que tenga sentido. al mismo tiempo, diferentes matrices especializadas deben ser de la misma clase base y, al mismo tiempo, conservar el mismo nombre, aunque con diferentes parámetros de plantilla. He pensado que podría haber una forma de hacerlo usando enable_if y escriba rasgos

+3

La primera contra pregunta es ¿qué tipo de problema está tratando de resolver con esto? –

Respuesta

2

Una posible solución era agregar un segundo parámetro de plantilla, por ejemplo bool especializado, de modo que el valor predeterminado sea falso y la plantilla especializada tenga ese parámetro cierto. Sin embargo, eso hace las cosas un poco complicadas ya que la instanciación necesita especificar un parámetro adicional.

Puede hacer template<class Foo, bool flag = false>, por lo que el segundo parámetro es opcional.

5

Se podía quedarse con todo el material genérico de un tipo separado, y se extienden de que con su especialización:

template <typename> struct S_generic { /* generic stuff here */ }; 

template <typename T> struct S : public S_generic<T> { /* nothing here */ }; 
template <> struct S<Foo> : public S_generic<Foo> { /* extra stuff here */ }; 

Editar: Como alternativa, si no te gusta el nombre adicional, la manera de utilizar una bandera adicional sin desorden al crear una instancia de la plantilla es usar un valor predeterminado:

template <typename T, bool fully_defined=true> struct S; 
template <typename T> struct S<T,false> { /* generic stuff here */ }; 

template <typename T> struct S<T,true> : public S<T,false> {}; 
template <> struct S<Foo,true> : public S<Foo,false> { /* extra stuff here */ }; 
+0

esto es lo que terminé haciendo. Lo que estaba tratando de evitar es tener dos nombres diferentes. Creo que podría haber una forma de hacerlo usando enable_if y escriba rasgos. – Anycorn

+0

No hay ninguna razón para agregar toda la complicación adicional de enable_if o rasgos de tipo, solo use una base común que no puede heredar de especializados y especializados. 'BlahBase' o' blah_base' son comunes. –

+0

en este momento no es tanto una pregunta práctica, como la cuestión de la curiosidad, "me pregunto si puede hacer esto". – Anycorn

Cuestiones relacionadas