IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage C++ Discussion :

specialisation de template


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Février 2006
    Messages
    153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 153
    Par défaut specialisation de template
    Bonjour

    J'ai commencé une classe de serialization de données dans un document xml. Pour cela, j'ai créé une interface ISerializable et une classe Archive :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    class ISerializable
    {
    public:
    	ISerializable() {}
    	virtual ~ISerializable() {}
     
    	virtual void Serialize(Archive& arch) const = 0;
    	virtual void DeSerialize(Archive& arch) = 0;
    };
     
    class Archive
    {
    	wxXmlNode* m_root;
     
    public:
    	Archive(wxXmlNode* root);
    	virtual ~Archive();
     
    	template <typename T>
    	bool Write(const wxString& name, const T& value);
     
    	template <typename T>
    	bool Read(const wxString& name, T& value);
    };
    et j'ai spécialisé les types simples :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    template <> 
    bool Archive::Write<int>(const wxString& name, const int& value);
     
    template <> 
    bool Archive::Read<int>(const wxString& name, int& value);
     
     
    template <> 
    bool Archive::Write<double>(const wxString& name, const double& value);
     
    template <> 
    bool Archive::Read<double>(const wxString& name, double& value);
     
    ...
    Mais j'aurai aussi souhaité pouvoir archiver des classes ISerializable. Par contre, je ne peux spécialiser une classe abstraite (enfin, ça ne sert à rien). Une solution (qui est celle que j'ai implémenté pour le moment), et de créer une autre methode :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    class Archive
    {
    	...
     
    	bool WriteObject(const wxString& name, const ISerializable& value);
     
    	bool ReadObject(const wxString& name, ISerializable& value);
    };
    mais cela casse l'API. J'aurai préféré garder uniquement Read et Write. En effet, je souhaiterai aussi pouvoir archiver des conteneur de données :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    // PSEUDO CODE ...
    template <typename CONTAINER, typename VALUE>
    bool Archive::Write(const wxString& name, const CONTAINER& value)
    {
       for (CONTAINER::const_iterator it = value.begin(); it != value.end(); ++it) {
          Write(name, *it); // *it est de type VALUE
       }
    }
    Puis je faire ceci ? Quelles pistes me conseillez vous ?

  2. #2
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    Tu peux passer par une fonction intermédiaire privée, qui elle sera spécialisée sur un booléen et le type.

    La valeur du booléen est true si la classe dérive de Serializable. Donc, en gros,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
     
    template <class P, class C>
    struct inherit
    {
      typedef char one[1];
      typedef char two[2];
      static one test(P*);
      static two test(...);
      static const bool value = (sizeof(test((C*)0)) == sizeof(one));
    };
     
    class Archive
    {
    private:
      template <class T, bool serializable>
      bool ReadHelper(const std::string& name, T& value);
     
      template <class T, bool serializable>
      bool WriteHelper(const std::string& name, const T& value);
     
    public:
      template <class T>
      bool Read(const std::string& name, T& value)
      {
        return ReadHelper<T,inherit<ISerializable, T>::value>(name, value);
      }
     
      template <class T>
      bool Write(const std::string& name, const T& value)
      {
        return WriteHelper<T,inherit<ISerializable, T>::value>(name, value);
      }
    };
     
    template <class T>
    bool Archive::ReadHelper<T,true>(const std::string& name, ISerializable& value)
    {
      return value.DeSerialize(name);
    }
     
    template <class T>
    bool Archive::WriteHelper<T,true>(const std::string& name, const ISerializable& value)
    {
      return value.Serialize(name);
    }
     
    template <bool serializable>
    bool Archive::WriteHelper<int,serializable>(const std::string& name, const ISerializable& value)
    {
    ...
    }
     
    template <bool serializable>
    bool Archive::WriteHelper<float,serializable>(const std::string& name, const ISerializable& value)
    {
    ...
    }
     
    ...
     
    // a partir de là, tu sais comment faire.
    Au lieu de faire une déduction statique du type du paramètre, tu forces le compilateur à ne rien faire de plus si le type passé en paramètre hérite de ISerializable. Du coup, toutes les classes sérialisables vont utiliser cette implémentation.

    Du coup, il t'es enfin possible de "spécialiser sur le type abstrait"
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  3. #3
    screetch
    Invité(e)
    Par défaut
    au leiu de la généricité, ca ressemble plus a de l'overload

  4. #4
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Par défaut
    Citation Envoyé par screetch Voir le message
    au leiu de la généricité, ca ressemble plus a de l'overload
    L'intérêt, c'est que cet "overload" via des templates est extensible, ce qui est intéressant dans certains cas (y compris celui-là, où l'utilisateur peut souhaiter utiliser ses propres classes de base pour la sérialisation).
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  5. #5
    screetch
    Invité(e)
    Par défaut
    oui, après consultation de mes archives personnelles, j'ai vu que je faisais pareil ^^ commentaire un peu inutile donc

  6. #6
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    template <class P, class C>
    struct inherit
    {
      typedef char one[1];
      typedef char two[2];
      static one test(P*);
      static two test(...);
      static const bool value = (sizeof(test((C*)0)) == sizeof(one));
    };
    Roooo j'avais complètement oublié ce code. Je crois qu'il tiré directement de Exceptionnal C++ si mes souvenirs sont exacts !
    J'aurais au moins vu un cas d'utilité un jour !

Discussions similaires

  1. Réponses: 10
    Dernier message: 16/04/2012, 13h53
  2. Specialisation de template
    Par Ulmo dans le forum Langage
    Réponses: 3
    Dernier message: 03/03/2009, 15h34
  3. specialisation de template
    Par camboui dans le forum Langage
    Réponses: 2
    Dernier message: 29/01/2009, 14h16
  4. specialisation de fonction template
    Par chubinou dans le forum Langage
    Réponses: 8
    Dernier message: 13/11/2007, 14h03
  5. Réponses: 5
    Dernier message: 29/12/2005, 21h27

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo