J'adore la correspondance de modèle de style Haskell.
J'ai mon code C ++ comme suit: P>
ObjectPtr ptr; if(ptr.isType<Foo>()) { // isType returns a bool Ptr<Foo> p = ptr.convertAs<Foo>(); // convertAs returns a Ptr<Foo> ...... } if(ptr.isType<Bar>()) { Ptr<Bar> p = ptr.convertAs<Bar>(); ...... }
6 Réponses :
dynamic_cast code> semblerait faire ce que vous voulez
Ensuite, faites une distribution dynamique sur le pointeur contenu - par exemple, si vous utilisez STD :: Auto_PTR (), faites-le du résultat de l'appel d'appel ().
J'aime la correspondance de modèle de style Haskell. P>
Ensuite, écrivez votre programme à Haskell. P>
Qu'est-ce que vous essayez de faire est un commutateur sur un type. C'est une chose commune que les gens font s'ils veulent éviter les fonctions virtuelles. Maintenant, ces derniers sont une pierre angulaire de ce que OO en C ++ est tout à propos. Si vous voulez les éviter, pourquoi vous programmez en C ++? p>
comme pour la raison pour laquelle cela est froncé sur: Imaginez que vous avez beaucoup de code comme celui-ci p>
xxx pré> éreinté sur votre code, puis quelqu'un vient et ajoute
baz code> aux types possibles que
pTR code> pourrait représenter. Maintenant, vous recherchez une base de code de gros code, essayant de trouver tous ces endroits où vous avez changé de type et essayez de découvrir lesquels vous devez ajouter
Baz code> à. P>
Et, comme Murphy l'a fait, juste lorsque vous avez fait, il existe un
foz code> pour être ajouté en tant que type. (Ou, en pensant à nouveau, si Murphy a sa façon de se glisser dans avant em> vous avez eu une chance trop complète Ajout de
Baz code>.) P> blockQuote>
Contrôle de la mémoire de faible niveau des constructeurs C. Constructeurs et destructeurs d'objets sur la pile <- Ceci est incroyable, car il donne des pointeurs intelligents, Raii, ...; Bibliothèque de modèles standard (une de ces fonctions virtuelles utilise-t-elle?). +1 En supposant que la réponse était une question authentique, pas de troll.
Ce n'était certainement pas une véritable question, mais cela n'était pas non plus un troll. C'était une question rhétorique. Être plain: Vous ne devriez pas faire cela en C ++ i>. C'est ce que les fonctions virtuelles ont été inventées pour; Ils mettent tout le code relatif aux objets du type FOO code> dans
FOO code> et tout ce qui concerne
Baz code> dans
Baz code >. Ce n'est pas toujours le meilleur que vous puissiez obtenir (témoin, par exemple, la motivation derrière le modèle de visiteur), mais c'est la valeur par défaut que vous devriez commencer par C ++.
Maintenant, ces derniers sont une pierre angulaire de ce que oo en C ++ est tout environ. Code> Alors pourquoi devrions-nous utiliser des métaprogramming de modèle quand il s'agit essentiellement de FP et non de OO, nous devrions tous aller à HASKEL au lieu d'utiliser le STL, booster ou utiliser nos propres modèles ... Rolleyes i> En outre seulement quelqu'un ignorant de la C ++ ferait une telle question, Comme ce gars (lien vers pdf) totalement désemparé!
@Ttrinidad: tandis que TMP est effectivement fp, ce n'est certainement pas OO. J'ai eu un regard très superficiel sur ce papier. Corrigez-moi si je me trompe, mais rien que je n'y ai vu à un premier coup d'œil annonce le type classique et simple Switch Type i> Le choix de l'OP, si commun dans C, qui pleure seulement pour le polymorphisme en C ++. Maintenant, j'avais librement admit à connaître à côté de rien sur Haskell et que mon exposition à Lisp était très courte et il y a une décennie il y a une décennie, alors je pourrais être complètement ici, mais je sais que ce que les désirs de l'OP sont fronçés en C ++ pour très bon les raisons. (J'ai une fois hérité de ce code et était chargé de Baz code> et
foz code>.)
@SBI Mach7 fait le type de commutation (qui n'est qu'une infime partie de ce qui est appelé correspondant à des modèles) et d'autres choses. Ood fournit des alternatives très verbeuses à la correspondance de motif (même le type de commutation). Imaginez créer une nouvelle méthode virtuelle et une implémentation dans chaque sous-classe pour chaque cas code>, c'est laid et sur le code, une douleur de maintenance et vous devez créer de nombreuses méthodes et même des sous-classes pour accomplir Le même commutateur simple code> fait. Dans ce cas, en utilisant des méthodes virtuelles, vous ne faites pas partie de la solution. Voir (Zip W / Source): goo.gl/hnokvo
@Ttrinidad: Si vous avez de nombreuses classes et que vous ajoutez fréquemment des algorithmes, les fonctions virtuelles ne sont pas bien adaptées. OOP a inventé le modèle de visiteur là-bas, mais je n'ai aucune difficulté à vous croire que d'autres langues ont d'autres constructions pour cela et qu'ils sont supérieurs dans certains, voire de nombreuses circonstances. J'ai également eu l'impression que Mach7 peut faire beaucoup de choses et que la capacité de basculer les types n'est qu'un sous-produit. Cependant, ce que le PO souhaité ici était un cas simple que vous résoudiez avec un taquage de type enum dans C. Pour cela, le polymorphisme est généralement meilleur dans de nombreux cas (les plus?).
Je suppose que votre modèle code> PTR code> a le concept d'un pointeur NULL.
ObjectPtr ptr; if(Ptr<Foo> p = ptr.convertAs<Foo>()) { // convertAs returns a NULL pointer if the conversion can't be done. ...... } if(Ptr<Bar> p = ptr.convertAs<Bar>()) { ...... }
Ce n'est-ce que cela ne fait que soulever une autre question - "Comment écrire des convertis () pour faire cela?"
@Neil: Pas vraiment - son code d'origine a supposé l'existence d'une convertis. Cela utiliserait probablement un dynamic_cast, qui produit un pointeur NULL s'il ne peut pas convertir un pointeur sur le type cible. En tant que telle, il est probable que cela soit déjà présent ou assez facile à mettre en œuvre s'il n'est pas présent.
La meilleure partie est, en C ++ 0x, vous pouvez remplacer PTR
auto code>.
A Pensez que cette macro fait précisément ce que vous voulez: usage: p> Je ne recommanderais pas ce genre de choses Dans le code qui est destiné à être lu par quelqu'un d'autre, mais depuis que vous avez mentionné le mot "macro" ... p> aussi, je ne voudrais pas faire quoi que ce soit à faire avec le motif correspondant à Haskell / Style ocaml. Vérifiez Scala si vous voulez une langue qui a une sémantique similaire à C ++ (puits, en quelque sorte) et une correspondance de motif véritable. P> p>
Tentative de simuler un style de correspondance de motif en C ++ à l'aide de RTTI est une idée soignée, mais elle est liée à des lacunes, car il existe des différences significatives entre les constructeurs de types de style HASKELL et Standard ML et les sous-classes C ++. (Remarque: ci-dessous, j'utilise Standard ML Syntaxe parce que je suis plus à l'aise avec elle.) P>
A :: B :: C :: DS code> lie les trois premiers éléments de la liste à A code>, B code> et C code> et le reste de la liste sur DS code>). En C ++, vous devrez toujours creuser dans les structures imbriquées réelles, à moins que vous ou quelqu'un d'autre ne propose de macros beaucoup plus compliquées que ce qui a été proposé ici. LI>
- in Haskell et standard ml, une déclaration de type de données de type constructeur de type
DataType 'A option = Aucune | Certains de 'A code> définissent un nouveau type: ' une option code>. Constructeurs Aucun code> et Certains code> ne sont pas des types, ce sont des valeurs avec des types 'une option code> et ' a -> 'une option code>, respectivement. En C ++, lorsque vous définissez des sous-classes telles que FOO code> et bar code> pour simuler les constructeurs de types, vous obtenez de nouveaux types. LI>
- in haskell et ml standard, constructeurs comme
Certains code> sont des fonctions de première classe qui construisent des valeurs du type de données auquel elles appartiennent. Par exemple, Carte Certains code> ont le type 'une liste ->' une liste d'options code>. En C ++, en utilisant des sous-classes pour simuler des constructeurs de types, vous n'obtenez pas cette capacité. Li>
- dans HASKELLL et ML standard, les fichiers de données sont fermés, de sorte que personne ne peut ajouter plus de constructeurs de types sans modifier la déclaration d'origine, et le compilateur peut vérifier au moment de la compilation que le match correspond à tous les cas. En C ++, vous devez vous aider à restreindre qui peut sous-classer votre classe de base. Li>
ul>
À la fin, obtenez-vous suffisamment d'avantages de la correspondance simulée de motif par rapport à l'utilisation de polymorphisme C ++ de manière plus typique? Utilise des macros pour faire un motif simulé correspondant légèrement plus concis (tout en l'obscurci pour tous les autres qui lit votre code) valent la peine? P>
Nous avons co-écrit une bibliothèque de correspondance de modèle pour C ++ qui vous permet de faire une analyse de motif et de type analyse de manière très efficace. La bibliothèque, appelée Mach7, a été publiée sous licence BSD et est disponible sur GitHub: https://github.com/ SOLODON4 / Mach7 . Vous pouvez trouver des vidéos, des affiches, des diapositives, des papiers ainsi que le code source là-bas. Il prend actuellement en charge GCC 4.4+, Clang 3.4+ et Visual C ++ 2010+. N'hésitez pas à poser des questions à propos de la bibliothèque en soumettant une question GitHub contre son référentiel. P>
Je suppose que vous êtes manquant
() code> après
istype code>.
Dans Mach7, votre code examinera comme suit: