heurté dans un autre problème de modèles:
Le problème: Je souhaite particulièrement spécialiser une classe de conteneurs (FOO) pour le cas que les objets sont des pointeurs et que je souhaite spécialiser uniquement la méthode de suppression. Devrait ressembler à ceci: p>
foo<int> fi;
foo<int*> fpi;
int i = 13;
fi.addSome (12);
fpi.addSome (&i);
fpi.deleteSome (12); // compiler-error: doesnt work
fi.deleteSome (&i); // compiler-error: doesnt work
fi.deleteSome (12); // foobase::deleteSome called
fpi.deleteSome (&i); // foo<T*>::deleteSome called
5 Réponses :
template <typename T> class foo { public: void addSome (T o) { printf ("adding that object..."); } void deleteSome (T o) { printf ("deleting that object..."); } void deleteSome (T* o) { printf ("deleting that object..."); } };
C'est une bonne suggestion, mais cela permet également aux cas suivants de compiler sans erreur: - FOO
@Kirill. Ça ne marchera pas. Supposons que nous utilisions foo addexe (myClass * o) code>,
Suppression (myClass * o) code> et
Suppression (myClass ** o) code>. La dernière fonction ne sera jamais appelée.
Je vais faire des courses maintenant. Mais je vous laisserai une note: vous ne pouvez pas mettre la spécialisation explicite pour le modèle de membre dans le corps de la classe. Vous ne pouvez pas non plus le mettre à l'extérieur, car cela ne fonctionnera pas: Modèle
<> code>).
@LitB, maintenant je vois de quoi vous parlez. Fixé.
+1 pour la deuxième solution. Cela semble bon. Voir ci-dessous pour une idée utilisant Boost :: Supprimer_Pointer, en évitant la fonction supplémentaire.
Vous pouvez utiliser l'héritage pour que cela fonctionne:
template <typename T> class foobase { public: void addSome (T o) { printf ("adding that object..."); } void deleteSome (T o) { printf ("deleting that object..."); } }; template <typename T> class foo : public foobase<T> { }; template <typename T> class foo <T *> : public foobase<T> { public: void deleteSome (T* o) { printf ("deleting that PTR to an object..."); } };
Merci Tony, je suppose que je vais avec votre solution.
Cette solution n'est pas évolutive. Supposons que vous souhaitiez ajouter une nouvelle fonction dosage (t O) et la spécialiser pour que les objets soient STD :: Liste
Aussi cette solution est fausse. Supposons que nous utilisons FOO de la classe foobase code> peut appeler
Supprimer code> car
Supprimer (t) code> sera appelé plutôt que
Suppression (t *) code>.
Euh, ne devrait-il pas être Classe FOO
* code>)?
La réponse de Kirill manque l'une des utilisations de spécialisation, à savoir spécialiser une classe existante pour votre propre nouveau type (sans avoir la possibilité de modifier la classe existante). La solution de Tony est la plus générale.
-1 Il n'y a aucune raison Supprimer code> doit être dans la classe de base sans être virtuelle, ramasser l'une des options.
Créer une classe de base pour une fonction unique faire une spécialisation partielle p> Utilisez votre classe de base p> Supprimer code>
Une autre solution. Utilisez la fonction auxiliaire deletésomeHelp code>.
template <typename T>
class foo {
public:
void addSome (T o) { printf ("adding that object...");
template<class R>
void deleteSomeHelp (R o) { printf ("deleting that object..."); }};
template<class R>
void deleteSomeHelp (R * o) { printf ("deleting that PTR to an object..."); }};
void deleteSome (T o) { deleteSomeHelp(o); }
}
Crazy Stuff :), mais je suis confronté au même problème ici, de sorte qu'un foo
+1 ressemble à celui que j'utiliserais tout de suite. C'est beaucoup plus simple et fait le travail.
Je n'ai pas encore vu cette solution, en utilisant Boost's activer_if code>
, isameame code>
et retirer_pointer code>
pour obtenir deux fonctions dans une classe, sans héritage ou autre cruft.
voir ci-dessous pour une version en utilisant seulement une version simplifiée est: p> et cela fonctionne sur MSVC 9: (a commenté les lignes qui donnent des erreurs, car elles sont incorrectes, mais bien d'avoir pour tester) p> retirer_pointer code>. p>
Mauvaise solution. Supposons que nous utilisons FOO. Supposons que certaines fonctionnalités du
foobase code> appels sont supprimées. Quelle fonction sera appelée? Droit! Supprimer (t) de la classe code> foobase code> plutôt que supprime (t *).
Question similaire: Stackoverflow.com/Questtions/1501357/... < / a>
@Malisov: Je crois que le point est que la foobase ne devrait pas être utilisée. C'est juste là pour rendre le piratage possible.
@splicer, mais sera utilisé i> utilisera implicitement si vous appelez une fonction autre que
Supprimer code>. À ce stade, si la fonction appelée appelle
Supprimer code>, il n'atteint jamais la fonction dans les cours dérivés.
@ Johannesschab-Litb Que se passe-t-il si la classe de base spécifie la fonction d'être virtuelle (et n'est pas instanciée)? J'ai vu ce problème / modèle de conception rampant avant: a-t-il un nom?