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

C++ Discussion :

Templates et friend


Sujet :

C++

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2003
    Messages : 29
    Points : 24
    Points
    24
    Par défaut Templates et friend
    J'ai realise un petit exercice sur les templates en c++, creation d'un pile avec templates, cependant j'ai des problemes avec l'affichage

    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
    62
    63
     
    #include <iostream>
    #include <string>
    using namespace std;
     
    template <class T>
    class stack {
      private:
        unsigned int size_max;
        unsigned int size;
        T*tab;
      public:
        stack(unsigned int);
        void operator << (const T&);
        void operator >> (T&);
        bool operator ++ () { return (size==size_max) ? true : false;}
        bool operator -- () { return (size==0) ? true : false;}
        friend ostream& operator << (ostream &, const stack<T> &); 
    };
     
    template <class T>
    stack<T> :: stack (unsigned int s) {
      tab = new T[s];
      size=0;
      size_max=s;
    }
     
    template <class T>
    void stack<T> :: operator << (const T& data) {
      if (size < size_max) {
        tab [size] = data;
        size++;
      } 
    }
     
    template <class T>
    void stack<T> :: operator >> (T& data) {
      if (size > 0) {
        size--;
        data = tab[size];
      }  
    } 
     
    template <class T>
    ostream& operator << (ostream &o, const stack<T> &in) {
      for (unsigned int i=0; i<in.size; i++) {
        cout << in.tab[i] << " ";
      }
      return o;  
    }
     
    int main () {
      stack<string> bla(10);
      bla << "dtc";
      bla << "mdr";
      bla << "w00t";
      string beuh;
      bla >> beuh;
      cout << bla << endl;
      cout << beuh << endl;
      system("pause");
      return 0;
    }
    avec visual studio c++ .net ca donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    essai error LNK2019: symbole externe non résolu "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class stack<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > const &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@ABV?$stack@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@@@Z) référencé dans la fonction _main
    essai fatal error LNK1120: 1 externes non résolus
    avec borland c++ builder 6 ca donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    [Linker Error] Unresolved external 'operator <<(_STL::basic_ostream<char, _STL::char_traits<char> >&, const stack<_STL::basic_string<char, _STL::char_traits<char>, _STL::allocator<char> > >&)' referenced from C:\PROGRAM FILES\BORLAND\CBUILDER6\PROJECTS\UNIT1.OBJ
    avec dev-cpp :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    F:/docs/C,C++/buseyne/labo11/labo11.cpp:17: warning: friend declaration `
       std::ostream& operator<<(std::ostream&, const stack<T>&)' declares a 
       non-template function
    F:/docs/C,C++/buseyne/labo11/labo11.cpp:17: warning: (if this is not what you 
       intended, make sure the function template has already been declared and add 
     
       <> after the function name here) -Wno-non-template-friend disables this 
       warning
    pour dev-cpp la solution est de mettre comme prototype:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    friend ostream& operator << <T>(ostream &, const stack<T> &);
    au lieu de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    friend ostream& operator << (ostream &, const stack<T> &);
    mais pour les autres je ne sais pas et je ne comprends pas.
    Si quelqu'un peut m'aider ...

    Merci d'avance

  2. #2
    Candidat au Club
    Profil pro
    Inscrit en
    Décembre 2003
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Décembre 2003
    Messages : 2
    Points : 2
    Points
    2
    Par défaut
    De mon côté, avec KDevelop & GPP, ca a compilé en faisant les modifications suivantes...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
        friend std::ostream& operator <<<T>(std::ostream&, const stack<T> &);

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

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1
    Points : 1
    Points
    1
    Par défaut
    A mon avis, le pb n'est pas dans le code mais dans l'organisation. Tout le code de la pile doit être dans le fichier .h,pas de fichier .cpp

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2003
    Messages : 29
    Points : 24
    Points
    24
    Par défaut
    tout se trouve dans un seul et unique fichier. Il ne devrait pas y avoir de probleme. Je n'arrive pas du tout a resoudre ce probleme, il n'a pas l'air de comprendre que l'operateur surcharge fonctionne aussi avec des templates.

    Kdevelop, GPP ca compile avec gcc donc le comportement est le meme que pour Dev-cpp qui utilise egalement gcc.

    pour visual studio ca a l'air de fonctionner si on ne scinde pas la declaration et le prototype

    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
     
    template <class T> class stack {
      private:
        unsigned int size_max;
        unsigned int size;
        T*tab;
      public:
        stack(unsigned int);
        void operator << (const T&);
        void operator >> (T&);
        bool operator ++ () { return (size==size_max) ? true : false;}
        bool operator -- () { return (size==0) ? true : false;}
     
    	friend ostream& operator << (ostream &o, const stack &in){
          for (unsigned int i=0; i<in.size; i++) {
            cout << in.tab[i] << " ";
          } return o;  
        } 
    };
    en tout cas, pour ce que j'ai lu sur le net, le support friend/template a l'air assez aleatoire et totalement dependant du compilateur. c'est dommage ca.

  5. #5
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    En fait, la déclaration de fonctions amies est vicieuse avec les templates. Ici lorsque tu vas instancier ta classe avec un paramètre int par exemple, celle-ci sera amie de l'opérateur << avec comme paramètre un stack<int>, et seulement lui. Pour résumer, il faudrait écrire une surcharge de l'opérateur << pour chaque type que tu utilises pour instancier stack, pour que ça compile.

    La solution est de déclarer la fonction template opérateur en tant qu'amie (et non sa surcharge pour le type T seulement), ainsi ton code original compilera.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    template <class T>
    class stack
    {
        template <class U> friend ostream& operator << (ostream& os, const stack<U>& s);
    };
     
    template <class T> ostream& operator <<(ostream& os, const stack<T>& s);
    {
        // ...
    }

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2003
    Messages : 29
    Points : 24
    Points
    24
    Par défaut
    merci pour l'explication.
    ca marche et je me coucherais moins con ce soir, que demander de plus ?

  7. #7
    Rédacteur
    Avatar de bigboomshakala
    Homme Profil pro
    Consultant Web .NET
    Inscrit en
    Avril 2004
    Messages
    2 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant Web .NET
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2004
    Messages : 2 077
    Points : 2 757
    Points
    2 757
    Par défaut
    Citation Envoyé par Asarnil
    que demander de plus ?
    une photo dédicacée de Monica Belucci en char* ...
    ... euh non, en string !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 27/01/2008, 21h22
  2. Déclarer un paramètre template comme friend
    Par YéTeeh dans le forum Langage
    Réponses: 4
    Dernier message: 11/04/2006, 14h00
  3. friend surcharge classe template
    Par fridollin dans le forum Langage
    Réponses: 4
    Dernier message: 15/11/2005, 21h37
  4. 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