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 :

Cast d'un type de base vers une classe que j'ai créée


Sujet :

C++

  1. #21
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    Citation Envoyé par Flob90 Voir le message
    Si tu ne mets pas en amie, le système des template fait qu'il ne sauras pas quel fonction appeler en cas de nécessité de conversion implicite (il n'arrivera pas à matcher les paramètre template).

    Le fait de déclarer la fonction en amie force le compilateur à l'utiliser si il peut et donc autorise les conversions implicites.
    Je m'aperçoit que ma question n'était vraiment pas précise.

    J'ai bien saisie la raison d'être du friend et que le problème tourne autour de la déclaration de fonction amies d'une classe template. Jusque là il n'y a pas de souci.

    Pour être précis, j'avais compris que la différence entre le code original et la correction apporté par Jean-Marc vient du fait que dans le premier cas on a une fonction template amie de la classe template alors que dans le second cas on a une fonction amie de cette classe template et qu'il n'y a pas de manière de déclarer une telle fonction dans la classe et de la définir en dehors.
    Est-ce que ma compréhension est bonne ?

    Citation Envoyé par Flob90 Voir le message
    Sortir la fonction c'est ce qu'avait fait l'op, et il n'avait pas utiliser friend car il n'avait pas besoin d'accéder à la classe. Cependant ici, le frien est obligatoire pour avoir une fonction bel et bien déclaré.
    Si la fonction (enfin le template de fonction) était bien friend dans le code original..

  2. #22
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    J'ai vraiment pas le temps... Le code de l'OP fonctionne si on vire les templates. Ceux qui comprennent comment http://en.wikipedia.org/wiki/Barton-Nackman_trick fonctionne devraient etre capables d'expliquer le probleme et la solution en detail.

    (Si il n'y a pas de reponses convenables, m'envoyer un mail dans 15 j. Avant je risque de l'oublier)

  3. #23
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet Voir le message
    J'ai vraiment pas le temps... Le code de l'OP fonctionne si on vire les templates. Ceux qui comprennent comment http://en.wikipedia.org/wiki/Barton-Nackman_trick fonctionne devraient etre capables d'expliquer le probleme et la solution en detail.
    Merci. En fait ça réponds à ma question et confirme bien ce que j'avais cru comprendre.

    Flob90, en relisant ta seconde intervention de manière plus attentive (et surtout en étant plus réveillé aprs quelques cafés), je viens de comprendre ce que tu cherches à expliquer. Le but est bien de remplacer une fonction template par une fonction non-template.

    PS : promis j'arrête de répondre le matin avant de prendre mon premier café. Comme ça je percuterais peut être sur les réponses qui ont été faites.

  4. #24
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Si l'aspect fonction non instantiation de template/instantiation de template semble clair (j'avais survolle un peu trop rapidement quand j'ai repondu ce matin), il me semble qu'un point qui risque de ne pas etre clair pour tout le monde est pourquoi ici une instantiation d'un template de fonctions ne permet pas l'utilisation de conversion implicite. (Je ne suis pas sur que ce soit aborde dans la page de Wikipedia). Si c'est bien le cas et que personne ne l'eclaire d'ici la, relancez moi dans 15 j, je risque de n'avoir pas le temps et d'oublier d'ici la.

  5. #25
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    Une autre ressource ou est présenté ceci est le Meyers, un des items traitant des templates.

    En effet le code de l'op utilisait aussi friend (lu trop vite), mais ca fonction était quand même template, ce qu'il ne faut pas. Je vais essayer de reformuler ce que j'ai dit (et de préciser un peu).

    Pour comprendre le pourquoi il faut comprendre comment le compilateur résout l'appel à une méthode

    Dans un premier temps il regarde si une fonction a été déclaré (pour savoir ou il regarde et dans quel ordre cf name lookup, des articles sur GotW notamment, ou dans la norme pour le détail), si une classe template a été déclaré avant, alors il vérifie aussi les fonction déclaré avec cette classe (dedans et amie), mais juste les fonctions de cette classe, pas les fonctions template. Si une fonction correspond il regarde alors si les paramètre sont bon (système des surcharges) si non il test les possibilités de conversion. Si il n'y a toujours pas de fonctions qui correspondent il regarde les fonction template et essaye de matcher les paramètre, si il y arrive il déclare la fonction correspondante et l'utilise, mais les paramètre doivent parfaitement matcher, ce qui interdit d'éventuelle conversion.

    Il est donc important que la fonction soit déclaré, ce qui est le cas avec une fonction d'une classe template (dés qu'une classe réel aura été déclaré d'après le modèle, ie dés qu'on va s'en servir généralement), mais pas avec une fonction libre template. Le fait que la fonction doivent être libre (et non membre) est aussi lié aux conversion implicites (pour permettre les appels du type 2+monType), donc la seul possibilité pour insérer la fonction dans la classe (pour qu'elle soit déclaré quand on l'utilisera) est d'utiliser l'amitié.

    Rapidement, le name lookup est l'ensemble des règle qui précise ou sont rechercher les noms des fonctions/méthodes lors des appels. Pour faire simple en premier le compilateur regarde dans les namespace des type des variables passé en paramètre (et dans la classe si l'on appel sur un objet). Puis il remonte progressivement les namespace jusqu'au global. Un autre point est que le compilateur s'arrête de chercher dés qu'il atteint un phase ou il y a des noms qui correspondent, si à cette étapes il n'y a pas moyen de faire correspondre les paramètre alors vous aurez une erreur de compilation (même si une fonction correspond bien dans le namespace supérieur).

    Je vais essayer de répondre à la question laissé en suspend par Jean-Marc Bourguet (ma réponse sera peut-être incomplète)
    pourquoi ici une instanciation d'un template de fonctions ne permet pas l'utilisation de conversion implicite.
    Le compilateur ne peut pas procéder à des conversion implicite à partir du template car il ne sait pas quel template choisir.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    template<class T>
    void foo(T, T) {}
     
    foo(0, 0.f); //foo<int> ou foo<float> ?
    Ce n'est pas le code de l'op mais c'est exactement la même chose (operator+<MonType<T> > ou operator+<int> ?)
    Si vous lui indiqué le type à utiliser alors pas de problème :
    <Petit HS>
    Pour donner un autre exemple ou ce mécanisme est important est lors de la création de constructeur de copie "généralisé" pour une classe template (ou d'opérateur d'affectation). Au mécanisme décrit au-dessus s'ajoute une chose pour les constructeur et fonction spécial du même genre (destructeur et opérateur d'affectation). Si la méthode recherchée est un constructeur par défaut, le compilateur va déjà regardé si vous n'en avez pas déclaré un, si ce n'est pas le cas il regarde si il peu en générer un (cf norme pour les conditions nécessaire, en gros les membres doivent avoir un constructeur par défaut et les classes de base aussi), si c'est le cas il le déclare et l'appel.

    Il va donc y avoir un problème si votre classe est template, que le compilateur peut générer le constructeur de copie et que vous voulez redéfinir un constructeur de copie "généralisé" (ie qui permet de copier depuis les autre classes basé sur ce modèle). L'idée est de faire ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    template<class T>
    struct A
    {
        template<class T> A(A<T>&) {/*code*/}
    };
    //A première vue tout est bon, sauf que si vous tentez d'appeler le constrcuteur de copie normal
    A<T1> a1; A<T1> a2(a1);
    //en vous attendant à utiliser votre constructeur template, vous allez avoir une surprise, car le mécanisme fait que le compilateur ne va pas voir de constructeur déclaré et va donc décider (comme il le peut) d'en générer un tout seul, résultat : pas ce que vous vouliez.
    C'est un autre exemple où ce mécanisme nous oblige à la prudence (surtout que là il n'y aura pas d'erreur de compilation) et à ne pas oublier de déclaré aussi notre propre constructeur de copie.
    </HS>

  6. #26
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    Petite rectification de mon post précédent, les conversions implicites sont tentées après avoir testé les templates. Ce qui ne change rien au problème.

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. Importation de données d'une base vers une autre
    Par jiluc dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 30/03/2006, 16h03
  2. Importation d'une base vers une autre
    Par PegasusDream dans le forum Access
    Réponses: 3
    Dernier message: 19/01/2006, 15h15
  3. RMAN : Duplication d'une base vers une autre
    Par Visiteur_33 dans le forum Recovery Manager
    Réponses: 2
    Dernier message: 03/11/2005, 14h40
  4. exporter des objets d'une base vers une autre
    Par RGShoop dans le forum Access
    Réponses: 3
    Dernier message: 07/09/2005, 11h52
  5. [héritage] cast avec le type de base
    Par Lere dans le forum C++
    Réponses: 6
    Dernier message: 16/09/2004, 18h21

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