2010-12-04 9 views
8

Récemment, j'ai utilisé l'une des fonctionnalités STL les moins utilisées, les allocateurs personnalisés, et j'ai besoin d'une aide sérieuse pour réduire mes frais généraux sémantiques. Prenons par exemple la définition d'une carte non ordonnée, qui mappe des noms de fichiers sur une carte non ordonnée d'une paire d'ints et d'une shared_ptr vers un Token, mais en utilisant un allocateur personnalisé.Réduction de la complexité des gabarits 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; 

Cela correspond à 404 caractères de définitions. Et puis pour le construire, je dois passer à la valeur par défaut pour chaque argument template, excepté l'Allocator, qui ne peut pas être construit par défaut, ET le nombre de godets, pour lequel aucune définition n'existe, résultant en 168 caractères juste pour construire le fichue chose. Plus, bien sûr, la même chose chaque fois que je veux insérer, car le type de valeur de la première carte doit être construit comme ça aussi.

Est-il possible que tout cela puisse être évité sans avoir à écrire ma propre carte non-ordonnée? Cela commence sérieusement à ralentir ma productivité.

Editer: Désolé! Je voulais dire, en général, pour les conteneurs STL, pas seulement unordered_map, c'est juste le pire des cas. J'ai aussi ce problème avec map, unordered_set, etc, et je ne peux pas écrire une fonction pour faire tout cela pour tous les conteneurs STL dont j'ai besoin.

+0

Vous recherchez peut-être une instanciation de modèle partielle? http://coding.derkeiler.com/Archive/C_CPP/comp.lang.cpp/2004-08/2307.html –

Répondre

6

solution de icecrime peut également être fait avec seulement un peu plus la laideur sur compilateurs plus anciens via le code ci-dessous . Vous pouvez également ajouter des fonctions d'usine pour simplifier la construction.

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

sinon celui-ci – diverscuba23

+0

C'est ce que j'ai fini par faire. C'est encore trop verbeux, mais c'est une grosse amélioration. Merci! – Puppy

6

Malheureusement, je ne peux pas fournir un exemple de code complet et compilable car je n'ai pas de compilateur C++ 0x ici. Cependant, je crois que C++ 0x template aliases pourrait être utile ici:

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; 

Encore une fois, désolé si cela ne compile pas.

Notez également que cela était déjà possible en C++ 03 en utilisant un autre type « indirection »:

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

J'aime celui-ci si C++ 0x est disponible. – diverscuba23

+0

"template alias" est la fonctionnalité que j'attends le plus, je regarde souvent le site web de gcc, espérant qu'il sera implémenté. Existe-t-il un compilateur qui implémente déjà cette fonctionnalité? – rafak

+0

N'est-il pas possible de simuler un alias de template avec un transfert parfait? – Ell