2008-10-30 14 views
7

¿Es posible typedef tipos largos que usan plantillas? Por ejemplo:typedefs para clases con plantillas?

template <typename myfloat_t> 
class LongClassName 
{ 
    // ... 
}; 

template <typename myfloat_t> 
typedef std::vector< boost::shared_ptr< LongClassName<myfloat_t> > > LongCollection; 

LongCollection<float> m_foo; 

Esto no funciona, pero ¿hay alguna manera de lograr un efecto similar? Solo quiero evitar tener que escribir y leer una definición de tipo que cubra casi todo el ancho de la ventana de mi editor.

Respuesta

14

No, eso no es posible actualmente. Será posible en C++ 0X AFAIK.

Lo mejor que puedo pensar es

template<typename T> struct LongCollection { 
    typedef std::vector< boost::shared_ptr< LongClassName<T> > > type; 
}; 

LongCollection<float>::type m_foo; 
+0

Eso funciona ... pero tendrá que duplicar todos sus ctors. –

+0

¿duplicar todos sus ctors? – dalle

+0

De hecho, ¿duplicar todos tus ctors? – mch

3

Si no desea seguir el camino macro que tiene que hacer typedefs individuales para cada tipo:

typedef std::vector< boost::shared_ptr< LongClassName<float> > > FloatCollection; 
typedef std::vector< boost::shared_ptr< LongClassName<double> > > DoubleCollection; 
+0

Esto es, después de todo, cómo std :: string es un typedef de std :: basic_string. –

2

No, pero puede acercarse usando un tipo de 'ayuda', vea esto example.

1

No es exactamente lo que estás pidiendo, pero esto podría lograr el efecto deseado dependiendo de su situación actual:

template <typename myfloat_t> 
class LongClassName 
{ 
    // ... 
}; 

template <typename myfloat_t> 
class LongCollection : public std::vector< boost::shared_ptr< LongClassName<myfloat_t> > > 
{ 
}; 

Es posible que necesite añadir algunos constructores o los operadores en función de sus necesidades.

+0

No se deriva de colecciones STL considera malas? No tienen funciones virtuales. Creo que sería más seguro implementar LongCollection en términos de std :: vector usando is como una variable miembro. La herencia privada también puede ser una opción. – mch

+0

No se considera una buena práctica, pero en realidad no plantea los problemas que menciona siempre que no pretenda utilizar polimorfismos. –

2

La solución mostrada por Leon es canónica. Un poco de conocimiento de fondo: esto se llama una "metafunción (de plantilla)" porque básicamente es una "función" que se evalúa en tiempo de compilación. En lugar de valores, se trata de tipos: hay una lista de tipos de entrada (los argumentos de tipo) y hay un "valor de retorno": El typedef que declara el tipo de nombre "tipo".

“Invocación” funciona de forma análoga a invocación de la función normal, aunque con una sintaxis diferente:

// Normal function 
result = f(args); 

// Metafunction 
typedef f<args>::type result; 

Esta construcción de código es un idioma utilizado a menudo en las bibliotecas, tales como las bibliotecas Boost e incluso en el STL en uno lugar: allocator_type::rebind<U>::other logra lo mismo con la única diferencia de que el typedef type se llama other.

+0

Creo que quieres decir 'temlate metafunction'. :) –

+0

Sí, más la "p". ;-) Gracias. –

Cuestiones relacionadas