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++

  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 !

  7. #7
    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 poukill Voir le message
    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 !
    Il est tiré d'un peu partout : c'est une application assez standard de SFINAE. On le retrouve souvent (sous une forme ou une autre) dans la librairie standard.

    Au fait, une petite erreur : les

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    template <bool serializable>
    bool Archive::WriteHelper<float,serializable>(const std::string& name, const ISerializable& value)
    {
    ...
    }
    sont en fait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    template <>
    bool Archive::WriteHelper<float,false>(const std::string& name, const float& value)
    {
    ...
    }
    Vous aurez corrigé (en partie au moins) vous même
    [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.

  8. #8
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    Citation Envoyé par poukill Voir le message
    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 !

    C'est pas tiré de là nan. C'est apparu y'a bien plus longtemps. (cf SFINAE trick etc). et la majorité des tricks à base de SFINAE se basent sur ce squelette. (ou enable_if etc)
    (j'ai une bafouille là dessus d'ailleurs, faudrait que je le dépoussiére.)

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