2009-10-02 9 views
10

Recuerdo granjas algo como esto se está haciendo:Lista de argumentos de plantilla de longitud variable?

template <ListOfTypenames> 
class X : public ListOfTypenames {}; 

es decir, X hereda de una lista de longitud variable de typenames pasados ​​como los argumentos de plantilla. Este código es hipotético, por supuesto.

No obstante, no he encontrado ninguna referencia para esto. ¿Es posible? ¿Es C++ 0x?

Respuesta

23

Puede hacerlo en C++ actual. Usted da la plantilla de un número "suficientemente grande" de los parámetros, y se les da por defecto:

class nothing1 {}; 
class nothing2 {}; 
class nothing3 {}; 

template <class T1 = nothing1, class T2 = nothing2, class T3 = nothing3> 
class X : public T1, public T2, public T3 {}; 

O puede obtener más sofisticados y el uso de recursividad. En primer lugar, con visión de declarar la plantilla:

class nothing {}; 

template <class T1 = nothing, class T2 = nothing, class T3 = nothing> 
class X; 

Entonces usted se especializa en el caso en todos los parámetros por defecto son:

template <> 
class X<nothing, nothing, nothing> {}; 

A continuación, defina adecuadamente la plantilla general (que previamente se haya solamente hacia adelante -declarado):

template <class T1, class T2, class T3> 
class X : public T1, public X<T2, T3> 

Observe que en la clase base, hereda X pero omite el primer parámetro. Entonces todos se deslizan a lo largo de un lugar. Eventualmente todos serán valores predeterminados, y la especialización se activará, lo que no heredará nada, por lo tanto, terminará la recursión.

Actualización: sólo tenía una sensación extraña que había publicado algo como esto antes, and guess what...

+0

también se podría utilizar una sola clase "nada" – sellibitze

+0

@sellibitze - utilizo uso una sola clase "nada" en el versión recursiva. No puede usar la misma clase para los valores predeterminados en la versión no recursiva, porque obtendrá errores de "nada es ya una clase base directa". –

+0

No entiendo: ¿por qué se saltea el primer parámetro al heredar de X? – Gili

19

Suena como que usted se refiere a C++ 0x Variadic Templates. También puede lograr el mismo efecto utilizando la construcción TypeList de Alexandrescu desde Loki.

Creo que la sintaxis de la plantilla variadic en cuestión sería similar a la siguiente.

template <typename...T> 
class X : public T... {}; 
+13

Si no me equivoco, también tendrá que descomprimir el tipo: 'public T ... {};' – UncleBens

2

El número de variable de las plantillas forma parte del siguiente estándar de C++. Sin embargo, puede probarlo si está usando GCC (desde la versión 4.3). Aquí hay un list of available C++0x features in GCC. Está buscando Plantillas Variadas.

Por cierto, si necesita una referencia formal sobre cómo lograr el mecanismo de herencia descrito por Earwicker, está en el libro C++ Templates.

4

Como ya se ha respondido, las plantillas variadic forman parte del siguiente estándar, pero se pueden emular en el C++ actual. Una herramienta conveniente para esto es usar la biblioteca Boost.MPL. En su código, usted escribe un único parámetro de plantilla (llamémoslo "Lista de tipos"), y los usuarios de su plantilla envuelven la lista de tipos en una secuencia MPL. Ejemplo:

#include "YourType.h" 
#include "FooBarAndBaz.h" 
#include <boost/mpl/vector.hpp> 

YourType<boost::mpl::vector<Foo, Bar, Baz> > FooBarBaz; 

En la aplicación de "YourType", se puede acceder a los elementos de la lista de Tipos con varios metafunciones. Por ejemplo, at_c<Typelist, N> es el elemento N de la lista.Como otro ejemplo, la clase "X" en su pregunta se podría escribir con inherit_linearly como:

//Warning: Untested 
namespace bmpl = boost::mpl; 
template<class Typelist> 
class X : bmpl::inherit_linearly<Typelist, bmpl::inherit<bmpl::_1, bmpl::_2> >::type 
{ 
... 
}; 
Cuestiones relacionadas