2010-09-12 10 views
7

Un ejemplo sencillo:¿Se puede acceder al parámetro de plantilla fuera de una plantilla sin un typedef?

template<typename _X> // this template parameter should be usable outside! 
struct Small { 
    typedef _X X; // this is tedious! 
    X foo; 
}; 

template<typename SomeSmall> 
struct Big { 
    typedef typename SomeSmall::X X; // want to use X here! 
    SomeSmall bar; 
    X toe; 
}; 

¿Hay una manera de acceder al parámetro de plantilla X de Small sin necesidad de utilizar un typedef en la clase Small?

+4

El nombre '_X' está reservada en C++; es mejor que nunca prefieras los nombres con un guión bajo, de esa manera no tienes que preocuparte por las diversas reglas de subrayado. –

+0

Uups - fue solo por el ejemplo, pero es bueno saberlo. – Danvil

Respuesta

3

Dependiendo de lo que está haciendo, template template parameters podría ser una mejor opción:

// "typename X" is a template type parameter. It accepts a type. 
// "template <typename> class SomeSmall" is a template template parameter. 
// It accepts a template that accepts a single type parameter. 
template<typename X, template <typename> class SomeSmall> 
struct Big { 
    SomeSmall<X> bar; // We pass X to the SomeSmall template. 
    X toe; // X is available to this template. 
}; 

// Usage example: 

template<typename X> 
struct Small { 
    X foo; 
}; 

struct MyType {}; 

// The foo member in Small will be of type MyType. 
Big<MyType, Small> big; 
+0

Para mi aplicación, este fue de hecho el mejor camino a seguir. – Danvil

8

Sí, defina una segunda plantilla "getter" con especialización parcial.

template<typename> 
struct get_Small_X; // base template is incomplete, invalid 

template< typename X > // only specializations exist 
struct get_Small_X< Small<X> > { 
    typedef X type; 
}; 

Ahora en lugar de Small<X>::X que tienen typename get_Small_X< Small<X> >::type.

Por cierto, _X es un identificador reservado, por lo que no debe usarlo para nada. X_ es una mejor opción.


Tema avanzado: plantilla de introspección.

Mientras lo pienso, no necesita definir esto por separado para cada plantilla. Una sola plantilla maestra debería hacerlo.

Esto se compila en Comeau, sé que hay reglas sobre la coincidencia de argumentos de plantilla, pero creo que está bien ... los argumentos de la plantilla están prohibidos en la plantilla maestra en especialización parcial.

template<typename> 
struct get_first_type_argument; 

template< template<typename> class T, typename X > 
struct get_first_type_argument< T<X> > { 
    typedef X type; 
}; 

template< typename X > 
struct simple; 

get_first_type_argument< simple<int> >::type q = 5; 

Esto solo funciona con plantillas "unarias" pero podría adaptarse en C++ 0x para el caso general.

+0

Bueno, todavía estás técnicamente usando un 'typedef'. :-) Pero esta es una solución inteligente. –

+1

@In silico: Eso ciertamente no es lo que significa OP. él dice "... en la clase Pequeña?" – Potatoswatter

+0

@Potatoswatter: Ah, solo estaba mirando el título de la pregunta en sí. –

Cuestiones relacionadas