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 fonction template


Sujet :

Langage C++

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3
    Par défaut specialisation de fonction template
    bonjour j'ai un petit probleme de template, je souhaite specialiser une fonction template avec un type template

    voici un exemple debile mettant en lumiere mon probleme

    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
     
    #include <list>
    #include <iostream>
     
    template<typename T> T plop(int i)
    {
      return T();
    }
     
    template<> int plop<int>(int i)
    {
      return i;
    }
     
    template<typename T>
    std::list<T>
    plop<std::list<T> >(int l)
    {
      std::list<T> list;
      for (int i =0; i < l; i++)
        {
          list.push_back(plop<T>(i));
        }
      return list;
    }
     
     
    int main()
    {
      std::list<int> l = plop<std::list<int> >(5);
     
      for (std::list<int>::iterator i = l.begin();
           i != l.end(); i++)
          std::cout << *i << std::endl;
    }
    et le compilo me retourne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    test.cc:16: error: function template partial specialization ‘plop<std::list<T, std::allocator<_CharT> > >’ is not allowed
    test.cc: In function ‘int main()’:
    test.cc:30: error: call of overloaded ‘plop(int)’ is ambiguous
    test.cc:4: note: candidates are: T plop(int) [with T = std::list<int, std::allocator<int> >]
    test.cc:16: note:                 std::list<T, std::allocator<_CharT> > plop(int) [with T = std::list<int, std::allocator<int> >]
    Je crois qu'il me dit que mes deux fonctions sont potentiellement acceptable puisqu'il ne voit pas le fait que std::list<T> est deja une specialisation

    je ne sais pas comment corriger ca
    merci d'avance pour votre aide

  2. #2
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Il te dit surtout et pour commencer qu'on ne peut pas faire de spécialisation partielle de fonction template. Résouds ce problème-là -- on en a déjà parlé dans le passé -- et je crois que la deuxième erreur disparaîtra. Au pire, elle sera dans un contexte plus clair.

  3. #3
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par défaut
    Salut,
    personnellement, dans ton cas, je surchargerais plutôt que de spécialiser :
    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
    #include <list>
    #include <iostream>
     
    template<typename T> T plop(int i)
    {
      return T();
    }
     
    template<> int plop<int>(int i)
    {
      return i;
    }
     
    template<typename T, 
             template<typename ELEM,
                      typename ALLOC > 
             class CONT>
    CONT<T, std::allocator<T> >
    plop(int l)
    {
      CONT<T> list;
      for (int i =0; i < l; i++)
        {
          list.push_back(plop<T>(i));
        }
      return list;
    }
     
     
    int main()
    {
      std::list<int> l = plop<int, std::list>(5);
     
      for (std::list<int>::iterator i = l.begin();
           i != l.end(); i++)
          std::cout << *i << std::endl;
     
      return 0;
    }
    Tu as comme ça une fonction qui accepte n'importe quel conteneur qui implémente push_back

  4. #4
    screetch
    Invité(e)
    Par défaut
    ca ne marche pas mieux, c'est toujours le meme probleme :-/

  5. #5
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par défaut
    Ah bon, le code ne compile pas chez toi ? Ou alors j'ai mal compris le but recherché.

  6. #6
    Candidat au Club
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3
    Par défaut
    en effet ca ne compile pas non plus chez moi.

    le code que j'utilise reellement a pour objectif de faire de la serialisation, deserialisation de donné via un systeme de template. Pour le moment la serialisation marche sans probleme, mais j'ai des soucis sur la deserialisation.

    grosso modo voila a quoi mon code ressemblera a la fin

    typedef std::list<std::pair<int, float> > MonType;

    Data d = marshal(foo); //avec foo de type MonType, ca ca marche pour le moment
    Montype bar = unmarshal<Montype>(d);

    donc mon probleme est que ma fonction unmarshal doit pouvoir etre template aussi bien avec des int qui ne sont pas template que avec des listes qui ont 1 parametre template ou avec des pairs qui en ont deux

    Résouds ce problème-là -- on en a déjà parlé dans le passé -- et je crois que la deuxième erreur disparaîtra
    J'ai pas vu comment (ou du moins, j'ai rien vu qui ne s'approche de mon probleme)

    sinon j'ai pensé qu'une solution de mon proleme pourait etre de passer mon objet de retour en reference, ainsi ce ne serait plus qu'un probleme de surchage. Mais j'aimerais bien quand meme savoir (histoire de ne pas mourir idiot) quel est la solution propre a ce probleme

    PS: desolé si je met du temps entre mes reponses, je finnirais par repondre.

  7. #7
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    Tu ne peux pas spécialiser une fonction template, mais tu peux le faire sur une structure ...

    Quelque chose comme :
    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
    template <typename Type>
    struct unmarshal
    {
    static Type Do (const Data& d)
    {
    // code "générique"
    }
    };
     
    template <> struct unmarshal<int>
    {
    static int Do (const Data& d)
    {
    // code pour int ...
    }
    }
     
    // etc ...
    Cela ne convient pas ?

  8. #8
    Candidat au Club
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3
    Par défaut
    merci ca a l'air de marcher

  9. #9
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par défaut
    Il manquait simplement un std::allocator<T> pour que ça compile correctement. VS2003 ne me signalait pas l'erreur.

    Ce code-ci devrait passer sans problème :

    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
    #include <list>
    #include <iostream>
     
    template<typename T> T plop(int i)
    {
      return T();
    }
     
    template<> int plop<int>(int i)
    {
      return i;
    }
     
    template<typename T, 
             template<typename ELEM,
                      typename ALLOC > 
             class CONT>
    CONT<T, std::allocator<T> >
    plop(int l)
    {
      CONT<T, std::allocator<T> > list;
      for (int i =0; i < l; i++)
        {
          list.push_back(plop<T>(i));
        }
      return list;
    }
     
     
    int main()
    {
      std::list<int> l = plop<int, std::list>(5);
     
      for (std::list<int>::iterator i = l.begin();
           i != l.end(); i++)
          std::cout << *i << std::endl;
     
      return 0;
    }

Discussions similaires

  1. Réponses: 3
    Dernier message: 29/03/2009, 10h21
  2. Pointeur sur une fonction template
    Par Progs dans le forum Langage
    Réponses: 2
    Dernier message: 15/02/2006, 20h25
  3. Fonction template virtuelle... comment l'éviter ?
    Par :Bronsky: dans le forum Langage
    Réponses: 12
    Dernier message: 07/06/2005, 14h21
  4. fonctions template
    Par romeo9423 dans le forum Langage
    Réponses: 12
    Dernier message: 22/01/2005, 16h13
  5. Fonctions template+friend sous VC7
    Par patapetz dans le forum MFC
    Réponses: 12
    Dernier message: 24/09/2004, 11h16

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