2010-03-01 9 views
1

J'ai une exigence où j'ai un ensemble de classes et ils ont une correspondance un à un avec un autre ensemble de classes. Pensez à quelque chose comme çaMappage entre deux ensembles de classes

a)

template < class A > 

class Walkers 
{ 
    int walk(Context<A>* context); 
}; 

L'ensemble des classes de contexte ne sont pas des modèles. Ce sont des classes individuelles. J'ai besoin de créer une correspondance entre ces deux ensembles. Une façon, je pourrais penser à est de créer une typelist et se référer à la classe à l'endroit approprié. Mais je pense que c'est plus sujet aux erreurs, car je peux confondre les Contextes dans la typelist. Quelqu'un peut-il me conseiller comment faire cela?

Merci, Gokul.

Répondre

1

Je ne suis pas sûr de comprendre ce que vous voulez faire, quels sont vos besoins ou objectifs sont, mais vous pouvez essayer d'utiliser des caractères pour définir la relation:

// direct mapping 
template <typename T> 
struct context_of; 

template <> 
struct context_of<A> { 
    typedef ContextA type; 
}; 

// reverse mapping 
template <typename T> 
struct from_context; 

template <> 
struct from_context<ContextA> { 
    typedef A type; 
}; 

Le code affiché serait écrit :

template <typename T> 
class Walker { 
public: 
    typedef typename context_of<T>::type context_type; 
    int walker(context_type* context); 
}; 

pour réduire la saisie, vous pouvez construire les applications de TypeListes (éventuellement complexe), ou vous pouvez utiliser une macro d'aide (plus sale, plus simple):

#define GENERATE_CONTEXT_ENTRY(the_class, the_context) \ 
    template <> struct context_of<the_class> { \ 
     typedef the_context type; }; \ 
    template <> struct from_context<the_context> \ 
     typedef the_class type; }; 

GENERATE_CONTEXT_ENTRY(A, ContextA); 
GENERATE_CONTEXT_ENTRY(B, ContextB); 

#undef GENERATE_CONTEXT_ENTRY 
+0

Merci! C'est gentil. Cela résoudrait mon problème. – Gokul

+0

Pouvez-vous s'il vous plaît également poster la solution en utilisant des typologies. juste curieux de savoir. – Gokul

0

Pouvez-vous créer les modèles de classes de contexte et utiliser la spécialisation de modèle pour les implémenter?

+0

Eh bien! C'est une option, mais s'il existe une relation plusieurs-à-un, la spécialisation de modèle peut échouer. – Gokul

0

Utiliser boost :: mpl:

using boost::mpl; 
typedef map< pair< A, ContextA >, 
      pair< B, ContextB > > context_type_map; 

template <typename T> 
class Walker { 
public: 
    typedef at< context_type_map, T >::type context_type; 
    int walker(context_type* context); 
}; 

En fait, je crois que vous pouvez utiliser à peu près tout conteneur de type (boost::mpl::vector) pour stocker des paires et utiliser boost::mpl::find_if avec un prédicat qui extrait le premier élément du pair et compare.

+0

Pouvez-vous me suggérer une bonne page Web à lire sur boost :: mpl? – Gokul

+0

Sur le web, vous pouvez jeter un oeil à la documentation. La référence a de petits exemples d'utilisation que vous pouvez regarder à des fins simples comme celui-ci. Hors ligne, vous pouvez jeter un oeil à 'C++ Template Metaprogramming' par Dave Abrahams il a une couverture des bibliothèques MPL et PP. –

Questions connexes