2009-12-29 3 views
1

Je travaille avec des classes générées avec un polymorphisme cassé. Pour chaque classe T générée, il existe une poignée de classes T_type_info, T_writer, T_reader qui ne sont liées qu'à T conceptuellement.Types de retour de modèle/Cast en fonction du modèle

Ce que je suis en train de faire est quelque chose comme ceci:

template <class T> class Wrapper 
{ 
public: 
    template <class W> W topic_cast(BrokenBaseClassWriter* p); 
    // other operations with the same problem ... 
}; 

template <> class Wrapper<MyTopic> 
{ 
public: 
    template <> MyTopicWriter* topic_cast(BrokenBaseClassWriter* p) { ... } 
}; 

Alors que je peux faire des choses comme:

void Write(const Wrapper<T>& topic) 
{ 
    BrokenBaseClassWriter p = not_important; 
    topic.topic_cast(p)->do_stuff(); 
} 

Mes classes T sont générées à partir d'un IDL et sont des concepts qui exister dans l'espace d'application. Ils ne dérivent de rien. Dans mon exemple ci-dessus, W n'est pas vraiment un paramètre indépendant, c'est "Quelque chose qui ne dépend pas de T". J'essaie de garder toutes les connaissances de T dans l'application, et toutes les connaissances de T '(sans savoir sur T) dans le backend.

Le compilateur dit cependant que ma fonction topic_cast n'est pas une fonction de modèle - je pense que parce que le modèle se produit dans le type de retour et qu'il ne pourrait pas être distingué d'autres instanciations. Je sais que cela (les modèles ne diffèrent que par le type de retour) n'est pas légal. Seulement dans mon cas ce serait vraiment unique parce que W n'est pas un paramètre indépendant. Mais discuter avec le compilateur est rarement utile.

Est-ce que je peux le faire, ou y a-t-il une autre façon de faire ceci "cast en fonction du type de template"?

Répondre

1

Cela ne peut-il pas être réalisé avec un système de traits?

template <typename T> struct my_traits 
{ 
}; 

template <> struct my_traits<MyClass> 
{ 
    typedef MyWriter writer_type; 
}; 

template <typename T> struct Wrapper 
{ 
    typename my_traits<T>::writer_type topic_cast(); 
}; 
+0

C'est ce que j'essayais d'obtenir avec la roue carrée que je construisais ci-dessus. Wrapper n'est plus nécessaire - le mapping de type était son but initial. Merci – swarfrat

0

Cela ne peut pas fonctionner:

topic.topic_cast(p)->do_stuff(); 

Parce que le compilateur ne peut pas déduire le type de retour.
Donc, vous devez dire explicitement le compilateur quel type vous souhaitez obtenir:

topic.topic_cast<MyType>(p)->do_stuff(); 

La mise en œuvre que vous fournissez est pour un type spécifique.
Ainsi, lorsque vous utilisez ce type spécifique que le code sera produit:

0

Cette compile avec gcc:

class BrokenBaseClassWriter; 
class MyTopic; 
class MyTopicWriter; 

template <class T> class Wrapper 
{ 
public: 
    template <class W> W *topic_cast(BrokenBaseClassWriter* p); 
    // other operations with the same problem ... 
}; 




template <> template<> 
MyTopicWriter *Wrapper<MyTopic>::topic_cast<MyTopicWriter>(BrokenBaseClassWriter* p) 
{ 
    return 0; 
} 


int main(int argc, int argv) 
{ 
    BrokenBaseClassWriter* p = NULL; 
    Wrapper<MyTopic> caster; 
    MyTopicWriter *casted = caster.topic_cast<MyTopicWriter>(p); 
} 

Bien sûr, il expose encore MyTopicWriter dans votre code principal ...

Questions connexes