2010-12-04 12 views
8

Recientemente, he estado utilizando una de las funciones de STL menos utilizadas: asignadores personalizados, y necesito una ayuda seria para reducir mi sobrecarga semántica. Tomemos, por ejemplo, la definición de un mapa desordenado, que asigna nombres de archivos a un mapa desordenado de un par de entradas y un shared_ptr a un Token, pero utilizando un asignador personalizado.Reducción de la complejidad de la plantilla en C++

typedef std::pair<int, int> token_key_type; 
typedef std::unordered_map< 
    token_key_type, 
    std::shared_ptr<Token>, 
    std::hash<token_key_type>, 
    std::equal_to<token_key_type>, 
    Allocator< 
     std::pair< 
      const token_key_type, 
      std::shared_ptr< 
       Token 
      > 
     > 
    > 
> filename_map_value_type; 
std::unordered_map< 
    string, 
    filename_map_value_type, 
    std::hash<string>, 
    std::equal_to<string>, 
    Allocator< 
     std::pair< 
      const string, 
      filename_map_value_type 
     > 
    > 
> tokens; 

Eso es 404 caracteres de definiciones. Y luego, para construirlo, tengo que pasar el valor predeterminado para cada argumento de plantilla, excepto el Allocator, que no puede construirse por defecto, Y el recuento de cubos, para el que no existe definición, lo que da como resultado otros 168 caracteres solo para construir el maldita cosa. Además, por supuesto, lo mismo cada vez que quiera insertar, porque el tipo de valor del primer mapa también debe construirse así.

¿Hay alguna manera de que todo esto se pueda evitar sin tener que escribir mi propio mapa desordenado? En serio, está empezando a ralentizar mi productividad.

Editar: ¡Lo siento! Quise decir, en general, para contenedores STL, no solo unordered_map específicamente, es solo el peor de los casos. También tengo este problema con el mapa normal, unordered_set, etc., y no puedo escribir una función para hacer todo esto para todos los posibles contenedores de STL que pueda necesitar de manera personal.

+0

¿Quizás esté buscando la creación de instancias parciales de plantillas? http://coding.derkeiler.com/Archive/C_CPP/comp.lang.cpp/2004-08/2307.html –

Respuesta

6

solución de icecrime también se puede hacer con sólo un poco más la fealdad de los compiladores de edad avanzada mediante el código de abajo . También es posible que pueda agregar funciones de fábrica para simplificar la construcción.

template<typename K, typename V> struct unordered_map_type 
{ 
    typedef std::unordered_map< 
     K, 
     V, 
     std::hash<K>, 
     std::equal_to<K>, 
     Allocator< 
      std::pair<const K, V> 
     > 
    > type; 
}; 

typedef std::pair<int, int> token_key_type; 
typedef unordered_map_type<token_key_type, std::shared_ptr<Token> >::type filename_map_value_type; 
+0

de lo contrario, este – diverscuba23

+0

Eso es lo que terminé haciendo. Todavía es demasiado detallado, pero es una gran mejora. ¡Gracias! – Puppy

6

Desafortunadamente, no puedo proporcionar un ejemplo de código completo y compilable porque no tengo un compilador C++ 0x aquí. Sin embargo, creo que C++ 0x template aliases podría ser útil aquí:

template<class Key, class Value> 
using custom_unordered_map = std::unordered_map 
    < 
     Key, 
     Value, 
     std::hash<Key>, 
     std::equal_to<Value>, 
     Allocator<std::pair<const Key, Value>> 
    >; 

typedef custom_unordered_map<token_key_type, std::shared_ptr<Token>> filename_map_value_type; 
typedef custom_unordered_map<std::string, filename_map_value_type> your_typedef_name; 

Una vez más, lo siento si esto no se compila.

También tenga en cuenta que esto ya era posible en C++ 03 utilizando un tipo adicional 'indirecto':

template<class Key, class Value> 
struct custom_unordered_map 
{ 
    typedef std::unordered_map 
    < 
     Key, 
     Value, 
     std::hash<Key>, 
     std::equal_to<Value>, 
     Allocator<std::pair<const Key, Value> > 
    > type; 
}; 

typedef custom_unordered_map<token_key_type, std::shared_ptr<Token> >::type filename_map_value_type; 
typedef custom_unordered_map<std::string, filename_map_value_type>::type your_typedef_name; 
+0

Me gusta este si C++ 0x está disponible. – diverscuba23

+0

"alias de plantilla" es la función que más espero, a menudo miro el sitio web de gcc, esperando que se implemente. ¿Hay un compilador que ya implemente esta característica? – rafak

+0

¿No es posible simular alias de plantillas con un reenvío perfecto? – Ell

Cuestiones relacionadas