2008-08-25 9 views
70

C++ 0x tiene alias de plantilla (a veces referidos como template typedefs). Ver here. La especificación actual de C++ no.Templatededefs - ¿Cuál es su trabajo?

¿Qué te gusta utilizar? ¿Objetos contenedores o macros? ¿Sientes que vale la pena?

+3

GOTW se ocupó de este tema hace un tiempo: http://www.gotw.ca/gotw/079.htm –

Respuesta

102

¿Qué te gusta utilizar como trabajo? ¿Objetos contenedores o macros? ¿Sientes que vale la pena?

La forma canónica es utilizar un metafunción como así:

template <typename T> 
struct my_string_map { 
    typedef std::map<std::string, T> type; 
}; 

// Invoke: 

my_string_map<int>::type my_str_int_map; 

Esto también se utiliza en el STL (allocator::rebind<U>) y en muchas bibliotecas incluyendo Boost. Lo usamos ampliamente en un bioinformatical library.

Está hinchado, pero es la mejor alternativa el 99% de las veces. Usar macros aquí no vale las muchas desventajas.

(EDIT:. He modificado el código para reflejar Boost convenciones/STL como ha señalado Daniel en su comentario)

+3

Si usa 'tipo' en lugar de 'Tipo' (o además de) esto funcionará mejor con Boost.MPL. Lo cual puede ser útil, así que creo que es una buena convención para alentar. –

+0

¿esto realmente se llama una metafunción? Lo dudo. –

+5

@Zenikoder: es perfectamente razonable llamarlo una metafunción, y la mayoría de los expertos en metaprogramación de C++ lo hacen (por ejemplo, las personas de Boost). No existe una definición rigurosa, pero personalmente llamo a todo una metafunción que, en tiempo de compilación, produce un tipo o una constante de tiempo de compilación dada alguna entrada. Es decir, cualquier asignación de una entrada a una salida en tiempo de compilación. No sé si existe una definición más razonable o más ampliamente aceptada. Finalmente, ¿puedo preguntar por qué objeta este uso del término? –

10
template <typename T> 
struct my_string_map : public std::map<std::string,T> 
{ 
}; 

No debe heredar de clases que no lo hacen tener un destructor virtual. Está relacionado con los destructores en las clases derivadas que no se llaman cuando deberían estar y usted podría terminar con la memoria no asignada.

Dicho esto, podría ***** probablemente ***** salirse con la suya en el ejemplo anterior porque no está agregando más datos a su tipo derivado. Tenga en cuenta que esto no es un endoso. Todavía te aconsejo no hazlo. El hecho de que puede hacerlo no significa que debería.

EDITAR: Sí, esta es una respuesta a la publicación de ShaChris23. Probablemente me perdí algo porque apareció arriba de su mensaje en lugar de debajo.

+3

¿significa esto como una respuesta a la publicación de ShaChris23? –

+0

Estos no son foros, las publicaciones no aparecen en orden cronológico. Normalmente, esto sería un comentario. No puedes, así que tal vez una respuesta wiki de la comunidad habría hecho. De cualquier manera, la pregunta es bastante antigua. – GManNickG

+4

Noté que es bastante viejo, pero pensé que era bueno asegurarse de que no fomentara las prácticas incorrectas. Hablaré contigo más s tarde – xghost

0

A veces puede escribir explícitamente los typedefs no formulados para todos los tipos necesarios. Si la clase base está modelada en múltiples argumentos de plantilla con solo un tipo que desea ser typedefed, puede heredar una clase especializada con typedef efectivamente incluida en el nombre de clase heredado. Este enfoque es menos abstruso que el enfoque de metafunción.

Cuestiones relacionadas