10
votes

Pointeurs comme paramètres de modèle?

J'ai une classe de conteneurs, nous l'appellerons xxx

Je veux faire quelque chose de différent avec cette classe lorsque T est un type de pointeur, par exemple. Quelque chose le long des lignes de: xxx

où l'on attend en quelque sorte que le type du type pointu de la chose comme son paramètre. Malheureusement, cette syntaxe ne fonctionne pas bien et avec quelques creux, je n'ai pas trouvé de bon moyen d'obtenir quelque chose comme cela fonctionne.

Pourquoi le faire de cette façon? Je veux changer, dans une très grande application, comment certains de nos conteneurs fonctionnent lorsque le type est spécialisé sur est un pointeur vs non pas un pointeur - et idéalement, je voudrais le faire sans changer les ~ 1 000 places Dans le code où il y a des choses comme cvector vs cvector ou de tels jeux avec des spécialisations partielles semblaient être la voie à suivre.

Suis-je sur crack ici?


4 commentaires

Je pense que plus de contexte est nécessaire à ce que vous faites. Alors, qu'est-ce que c'est? Quelle est la classe wrapper "quelque chose"? Et qu'est-ce que cvector ? Pas réinventé std :: vecteur , j'espère.


Non, ce n'est pas - j'utilise des noms abstraits sur les classes intentionnellement - mais fondamentalement, la classe wrapper prend un type de pointeur comme paramètre. Cvector peut prendre tout type de type - je veux seulement utiliser la classe wrapper lorsque le vecteur reçoit un type de pointeur.


@D Garcia: Je ne comprends pas ce que vous voulez, exactement. Si T est un pointeur, que devrait faire la cvector?


Rien de spécial - quand T est un pointeur, je veux un cvecteur de wrapper S - sinon, je veux juste un cvector de TS


6 Réponses :


4
votes

Je ne pense pas que vous puissiez spécialiser une classe à l'aide de la syntaxe que vous décrivez ... Je ne sais pas comment cela pourrait éventuellement fonctionner. Ce que vous pouvez faire est de spécialiser la classe pour les pointeurs et de ré-implémenter ses tripes à l'aide de la classe wrapper autour des pointeurs bruts. Je ne sais pas si cela vous aidera, mais Cet article décrit les modèles de spécialisation des pointeurs .


2 commentaires

Merci - l'article que vous avez associé m'a donné un moyen de faire ce dont j'ai besoin.


Heureux d'avoir pu aider. Je ne suppose pas que vous aimeriez accepter ma réponse ou au moins donner une uppote, montrer une appréciation? :)



0
votes

Je ne pense pas que les modèles sont tout à fait flexibles.

Une approche de force très brutale serait de spécialiser pour tous vos types de pointeur ... qui défait le problème de l'utilisation de modèles.

Pourriez-vous avoir une autre classe CVector utilisée uniquement pour les vecteurs de pointeurs?


1 commentaires

Si je faisais un type différent, je devrais passer à travers tous les endroits du code où l'ancien type a été utilisé pour le basculer sur le nouveau type - moins qu'idéal, je recherche une chute de remplacement.



8
votes

Si je vous comprends correctement, cela pourrait faire ce que vous voulez:

template<typename T>
class CVector { ... };

template<typename T>
class CVector<T*> : public CVector< SomeWrapperClass<T> > {
public:
  // for all constructors:
  CVector(...) : CVector< SomeWrapperClass<T> >(...) {
  }
};


3 commentaires

HMM - Si je peux avoir la nouvelle classe être nommée la même chose que l'ancien - cela pourrait fonctionner. Si je dois renommer la classe, je suis de retour à devoir changer toutes les instanciations à une nouvelle classe, ce qui fonctionne, j'essaie d'éviter de devoir faire.


Il n'est toujours qu'un cvector <...> , juste qu'il pourrait hériter d'un autre cvector <...> en interne. Mais les utilisateurs de la classe ne devraient pas se soucier de ces détails internes, à condition que l'interface reste compatible.


+1 @garcia: la solution ci-dessus devrait fonctionner - vous pouvez vous reporter à votre utilisation de gabarit cvector sous forme de cvector vs cvector - et le modèle approprié sera utilisé (implémenté en termes de sinwrapper non pas )



6
votes

Cela fonctionne simplement bien en C ++ ...

#include <iostream>

template <class T>
class CVector
{
public:
    void test() { std::cout << "Not wrapped!\n"; }
};

template <class T>
class CVector<T*>
{
public:
    void test() { std::cout << "Wrapped!\n"; }
};

int main()
{
    CVector<int> i;
    CVector<double> d;
    CVector<int*> pi;
    CVector<double*> pd;
    i.test();
    d.test();
    pi.test();
    pd.test();
}


1 commentaires

Cela ne me laissera pas changer de paramètre de modèle sous condition s'il s'agit ou non d'un pointeur - déjà examiné ce que Boost a. Ce n'est pas un cas de code conditionnel - c'est un cas de dactylographie conditionnelle - les types de choses à l'intérieur de la classe doivent être différents selon si le paramètre Modèle est un pointeur ou non.



1
votes

0
votes

Je suis d'accord avec la réponse de Rlbond. Je l'ai modifié un peu pour répondre à votre besoin. Cvector peut être une classe dérivée du cvecteur lui-même. Vous pouvez ensuite utiliser différents membres et fonctions pour cela.

#include <iostream>
#include <string>
template <class T>
class CVector
{
public:
    void test() { std::cout << "Not wrapped!\n"; }
    void testParent() { std::cout << "Parent Called\n";}
};

template <class T>
class CVector<T*>:
    public CVector<T>
{
public:
    void test(std::string msg) { std::cout << msg; testParent(); }
};

int main()
{
    CVector<int> i;
    CVector<double> d;
    CVector<int*> pi;
    CVector<double*> pd;
    i.test();
    d.test();
    pi.test("Hello\n");
    pd.test("World\n");
    system("pause");
}


0 commentaires