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

MFC Discussion :

Fonctions template+friend sous VC7


Sujet :

MFC

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 55
    Points : 41
    Points
    41
    Par défaut Fonctions template+friend sous VC7
    Bonjour

    Dernièrement j'ai eu un problème en compilant un projet sous VC7 pour la première fois. Dans les classes templates, les opérateurs définis en tant que fonctions amies de la classe faisaient tous l'objet d'une erreur à l'édition des liens (fonction non définie). Un peu comme si j'avais mis les fonctions template dans un .cpp, alors qu'elles étaient bien dans le .h (et que ça avait toujours marché sous VC6). Ces fonctions (que ce soit des opérateurs ou des fonctions classiques ne changeait rien) se présentaient comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    template <class T>
    class A
    {
    public:
       friend void func(A<T>&);
    };
     
    template <class T>
    void func(A<T>& a)
    { /* du code */ }
    Après pas mal d'heure de prise de tête, je me rend enfin compte qu'il y a un moyen de faire enfin avaler à VC7 ces fonctions. Il fallait les présenter plutôt comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    template <class T>
    class A
    {
    public:
       friend void func(A<T>& a)
       { /* du code */ };
    };

    Bon ça semble très bien comme solution seulement je trouve que ce n'est pas très pratique pour des fonctions dont le corps serait un peu imposant. C'est une présentation à la Java, présentation que je n'aime justement pas. J'ai donc 2 questions :
    - pourquoi VC7 exige cette façon de présenter le code alors que VC6 se débrouillait très bien avec la première méthode ?
    - n'y a-t-il vraiment aucun moyen de séparer la déclaration de la définition pour des fonctions friend+template, sous VC7 ?

    Merci d'avance

  2. #2
    Membre à l'essai
    Inscrit en
    Juin 2004
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Juin 2004
    Messages : 20
    Points : 23
    Points
    23
    Par défaut
    En fait, tu as fait une erreur dans le premier code, il fallait faire comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    template <class T> 
    class A 
    { 
    public: 
       friend void func(A<T>&); 
    }; 
     
    template <class T> 
    void [b]A::[/b]func(A<T>& a) 
    { /* du code */ }
    Tu as juste oublié de spécifier que la fonction func faisait parti de la classe A. Pour le compilo, tu avais défini une fonction func qui n'appartient à aucune classe, et tu avais oublié de définir le code de la fonction func de la classe A.

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 55
    Points : 41
    Points
    41
    Par défaut
    Citation Envoyé par atchoum_69
    Tu as juste oublié de spécifier que la fonction func faisait parti de la classe A. Pour le compilo, tu avais défini une fonction func qui n'appartient à aucune classe, et tu avais oublié de définir le code de la fonction func de la classe A.
    Mais elle ne fait PAS partie de la classe A justement

    Euh... bon je suis pas à fond dans le c++ en ce moment mais une fonction amie est bien une fonction globale qui a des accès privilégiés sur une ou plusieurs classes, non ??

    De plus si l'erreur venait de là, cela provoquerait une erreur à la compilation, et non à l'édition des liens.

  4. #4
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 279
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 279
    Points : 11 015
    Points
    11 015
    Par défaut
    Pas globale mais externe à la classe ; cela peut être une fonction membre d'une autre classe.

    Tu utilises VC 7 ou 7.1 ? Essaies avec le dernier pour voir si le problème est corrigé (dispo avec le toolkit 2003). La version 7.0 n'est pas connue pour être très bonne vis-à-vis des templates.

    Autres endroits où chercher des infos :
    - les commentaires sur comment avoir un code portable qui se trouve sur le site de boost
    - fclc++ eventuellement pour vérifier ce qui est valide ou non.

  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 : 40
    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
    Sous VC 7.1 le problème se pose également.

    Mais je crois que c'est un problème de syntaxe et non de compilo, ce code compile et lie parfaitement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    template <class T>
    class A
    {
    public:
       template <class U> friend void func(A<U>&);
     
    };
     
    template <class T>
    void func(A<T>& a)
    {  }

  6. #6
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut Re: Fonctions template+friend sous VC7
    Citation Envoyé par patapetz
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    template <class T>
    class A
    {
    public:
       friend void func(A<T>&);
    };
     
    template <class T>
    void func(A<T>& a)
    { /* du code */ }
    Un extrait de la norme (14.5.3) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    template<class T> class task {
      // ...
      friend void process(task<T>*);
      // ...
    };
    [...]
    because process does not have explicit template arguments, each specialization of the task class template has an appropriately typed function process as a friend, and this friend is not a function template specialization;

    Je ne suis pas du tout certain de ce que ça veut dire, mais il semble que ce serait un indice que ton code initial est incorrect, et qu'il faudrait le remplacer par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    template <class T>
    class A
    {
    public:
       friend void func<T>(A<T>&);
    };
     
    template <class T>
    void func(A<T>& a)
    { /* du code */ }

  7. #7
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par Loulou24
    Mais je crois que c'est un problème de syntaxe et non de compilo, ce code compile et lie parfaitement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    template <class T>
    class A
    {
    public:
       template <class U> friend void func(A<U>&);
     
    };
    Ce code n'est pas équivalent, puisque qu'ici, func<T1> est friend de A<T2> pour tout T1 et T2, alors qu'il semblerait que le posteur initial ne souhaite que ce soit vrai que quand T1 == T2.

  8. #8
    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 : 40
    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
    J'ai aussi du mal à comprendre l'extrait que tu cites, et le code qui va avec (qui ne compile pas chez moi).

    Le code que j'ai donné était celui qui me paraissait le plus logique, je ne pense pas que notre posteur cherchait à faire une manip mystique avec sa fonction amie .

  9. #9
    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 : 40
    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 (pour ceux qui ont du mal comme moi ) j'ai réussi a comprendre l'exemple de la norme, ça signifie que la surcharge de la fonction pour T sera l'amie de A<T> :

    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
    template <class T>
    class A
    {
    public:
       friend void func(A<T>&);
     
    };
     
    void func(A<int>& a){ }
    void func(A<float>& a){ }
     
    int main()
    {
       A<int> v1;
       func(v1);
     
       A<float> v2;
       func(v2);
     
       return 0;
    }
    Par contre Loïc je n'arrive pas à voir ce que ton code est censé faire, ni à le compiler . Mais ça doit être un manque de VC7.1, car on retrouve également cet exemple dans la norme.

    En tout cas il faudrait que le posteur précise ce qu'il veut faire exactement.

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 55
    Points : 41
    Points
    41
    Par défaut
    Salut !

    Merci pour vos réponses, j'essaierai les différentes syntaxes proposées. Je n'ai malheureusement pas le temps de faire ça tout de suite, je suis très pris par le boulot... Je reviens vers vous dés que j'aurai testé.

    a+

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 55
    Points : 41
    Points
    41
    Par défaut
    Bonjour

    J'ai essayé tout ça, voici les résultats.

    Tout comme Loulou, je n'ai pas réussi non plus à compiler le code le Loïc.

    Par contre la syntaxe proposée par Loulou fonctionne parfaitement. Comme vous l'avez dit, dans son exemple func<T1> est amie de func<T2>, ce qui est plus général que ce que je souhaite. Mais je me suis dit que le fait de remplacer U par T permettait de résoudre ce petit inconvénient :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    template <class T> 
    class A 
    { 
    public: 
       template <class T> friend void func(A<U>&); 
     
    }; 
     
    template <class T> 
    void func(A<T>& a) 
    {  }
    Il me semble que comme ça, on a la garantie que l'affirmation ci-dessus n'est vraie que pour T1==T2, non ?
    Ce qui est sur, c'est que comme ça, ça compile et ça linke


    Citation Envoyé par Luc Hermitte
    fclc++ eventuellement pour vérifier ce qui est valide ou non.
    fclc++ ? Késako ??

  12. #12
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par patapetz
    Tout comme Loulou, je n'ai pas réussi non plus à compiler le code le Loïc.
    Et moi non plus avec VC++ 2005, mais si je le modifie ainsi, il compile :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    template <class T> class A;
     
    template <class T> void func(A<T>& a)
    { /* du code */ }
     
    template <class T>
    class A
    {
    public:
       friend void func<T>(A<T>&);
    };
    et il compile directement avec gcc 3.3.3.
    De plus, le code initial compilé avec gcc disait :
    template.cpp:14: warning: friend declaration `void func(A<T>&)' declares a non-template function
    template.cpp:14: 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
    Citation Envoyé par patapetz
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    template <class T> 
    class A 
    { 
    public: 
       template <class T> friend void func(A<U>&); 
     
    }; 
     
    template <class T> 
    void func(A<T>& a) 
    {  }
    Il me semble que comme ça, on a la garantie que l'affirmation ci-dessus n'est vraie que pour T1==T2, non ?
    AMA, ça n'apporte rien. C'est comme si tu écrivait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    {
      int i;
      {
        int i; // Pas le même i
      }
    }
    Citation Envoyé par patapetz
    Citation Envoyé par Luc Hermitte
    fclc++ eventuellement pour vérifier ce qui est valide ou non.
    fclc++ ? Késako ??
    fr.comp.lang.c++ un newsgroup. Un peu l'ancêtre des forums comme ici. Et qui rassemble quelques pointures. Par contre plus strict qu'ici en matière de sujet abordable (mais ce message y est acceptable à 100%).

  13. #13
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 55
    Points : 41
    Points
    41
    Par défaut
    Citation Envoyé par JolyLoic
    mais si je le modifie ainsi, il compile :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    template <class T> class A;
     
    template <class T> void func(A<T>& a)
    { /* du code */ }
     
    template <class T>
    class A
    {
    public:
       friend void func<T>(A<T>&);
    };
    et il compile directement avec gcc 3.3.3.
    De plus, le code initial compilé avec gcc disait :
    template.cpp:14: warning: friend declaration `void func(A<T>&)' declares a non-template function
    template.cpp:14: 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
    Intéressant comme information, je pense que c'est finalement la bonne syntaxe à adopter.

    Citation Envoyé par JolyLoic
    AMA, ça n'apporte rien. C'est comme si tu écrivait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    {
      int i;
      {
        int i; // Pas le même i
      }
    }
    Ouaip je m'en suis rendu compte hier soir en y repensant

    Citation Envoyé par JolyLoic
    Citation Envoyé par patapetz
    Citation Envoyé par Luc Hermitte
    fclc++ eventuellement pour vérifier ce qui est valide ou non.
    fclc++ ? Késako ??
    fr.comp.lang.c++ un newsgroup. Un peu l'ancêtre des forums comme ici. Et qui rassemble quelques pointures. Par contre plus strict qu'ici en matière de sujet abordable (mais ce message y est acceptable à 100%).
    OK, merci pour l'info !


    a+

Discussions similaires

  1. Fonction qui marche sous FF mais pas IE
    Par Oluha dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 25/01/2006, 14h07
  2. selectionner une catégorie en fonction d'une sous catégorie
    Par coolhead dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 24/08/2005, 15h57
  3. Problème fonction et trigger sous 7.2
    Par anoukhan dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 22/06/2005, 22h53
  4. Fonction template virtuelle... comment l'éviter ?
    Par :Bronsky: dans le forum Langage
    Réponses: 12
    Dernier message: 07/06/2005, 14h21
  5. fonctions template
    Par romeo9423 dans le forum Langage
    Réponses: 12
    Dernier message: 22/01/2005, 16h13

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