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 :

probleme spécialisation template


Sujet :

Langage C++

  1. #1
    Membre confirmé Avatar de babar63
    Homme Profil pro
    Développeur jeux vidéos/3d Temps réel
    Inscrit en
    Septembre 2005
    Messages
    241
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Développeur jeux vidéos/3d Temps réel

    Informations forums :
    Inscription : Septembre 2005
    Messages : 241
    Par défaut probleme spécialisation template
    Bonjour a tous,
    Etant encore a la decouverte du monde merveilleux des templates j'ai rencontré une erreur en essayant de spécialisé une fonction membre de ma classe template. Voila le code :
    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
     
    template<typename T>
    class Vector2D
    {
    public:
    ....
    //ma fonction à spécialiser :
    template<typename T2> static T2 norm(const Vector2D<T> & myVector2D); //fonction statique template permettant de calculer la norme et de retourner le type T2.
    };
     
    //declaration de la fonction :
    template<typename T>
    template<typename T2>
    T2 Vector2D<T>::norm(const Vector2D<T> & myVector2D)
    {
    	...//aucun probleme avec la declaration de cette fonction
    }
     
    //specialisation souhaité :s
    template<typename T>
    template<>
    int Vector2D<T>::norm(const Vector2D<T> & myVector2D)
    {
    	...//erreur de compilation la fonction ne correspond a aucun modele???
    }
    Voila le probleme je n'ai pas trouvé de solution pour spécialiser cette fonction (excepté remplacer le retour du type T2 par un argument supplémentaire!!) est-ce un probleme de syntaxe ou simplement c'est impossible?
    merci d'avance
    Bonne journée

  2. #2
    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
    La signature d'une fonction ne dépend que du nom et des arguments(leurs types) de cette fonction.
    Le type de retour n'est pas pris en compte.
    Autrement dit, tu dois par exemple rajouter un argument bidon qui serait du type de la valeur de retour.
    (pourquoi ne pas retourner un réel dans tous les cas ? Un entier est un réel, donc pas de soucis)

  3. #3
    Membre confirmé Avatar de babar63
    Homme Profil pro
    Développeur jeux vidéos/3d Temps réel
    Inscrit en
    Septembre 2005
    Messages
    241
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Développeur jeux vidéos/3d Temps réel

    Informations forums :
    Inscription : Septembre 2005
    Messages : 241
    Par défaut
    pourquoi ne pas retourner un réel dans tous les cas ? Un entier est un réel, donc pas de soucis
    Oui je suis d'accord avec toi mais si je retourne un float je risque une troncation dans le cas ou je travaillerai avec des doubles(par exemple), et si je retourne un double je perds de la "place" pour rien lorsque je travaille avec float, int...
    Ces détails sont peut etre dérisoires mais j'aime faire les choses bien
    Il n'existe donc pas d'autre solution que de rajouter un parametre supplémentaire?

  4. #4
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Dans le sens où tu t'attends sans doute à ce que le retour de ta fonction soit de type T (et non de type T2), pourquoi ne pas faire un truc du genre de
    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
     
    template <class T>
    class Vector2D
    {
        public:
            typedef typename T __type;
            typedef std::vector<__type> vector;
            Type Norme(const vector& tab)
            {
                 /*comportement par défaut*/
            }
    }
     
    template <>
    double Vector2D<double>::Norme(const std::vector<double>& tab)
    {
       /* compoirtement spécialisé pour les doubles */
    }
     
    template <>
    float Vector2D<float>::Norme(const std::vector<float>& tab)
    {
       /* compoirtement spécialisé pour les floats */
    }
    /* autres spécialisations */
    (je *crois* que cela devrait fonctionner comme cela )
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  5. #5
    Membre confirmé Avatar de babar63
    Homme Profil pro
    Développeur jeux vidéos/3d Temps réel
    Inscrit en
    Septembre 2005
    Messages
    241
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Développeur jeux vidéos/3d Temps réel

    Informations forums :
    Inscription : Septembre 2005
    Messages : 241
    Par défaut
    Oui ca dervrait fonctionner le probleme c'est que je ne m'attend pas a ce que le retour de ma fonction soit de type T!
    Par exemple si je travaille sur des vecteur entiers et je souhaite connaitre la norme, (excepté quelques cas bien rare) il me faut retourner un float.

  6. #6
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Mais, dans ce cas, pourquoi ne pas effectivement d'office travailler avec des réels pour le retour quelque chose qui deviendrait
    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
    template <class T>
    class Vector2D
    {
        public:
            typedef typename T __type;
            typedef std::vector<__type> vector;
            double /* ou float */ Norme(const vector& tab)
            {
                 double ret= /* calcule de la norme avec un transtypage de tous les __type en float */
                 return ret;
            }
    }
     
    template <>
    double Vector2D<double>::Norme(const std::vector<double>& tab)
    {
       /* compoirtement spécialisé pour les doubles */
    }
     
    template <>
    double Vector2D<float>::Norme(const std::vector<float>& tab)
    {
       /* comportement spécialisé pour les floats */
    }
    /* autres spécialisations */
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  7. #7
    Membre confirmé Avatar de babar63
    Homme Profil pro
    Développeur jeux vidéos/3d Temps réel
    Inscrit en
    Septembre 2005
    Messages
    241
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Développeur jeux vidéos/3d Temps réel

    Informations forums :
    Inscription : Septembre 2005
    Messages : 241
    Par défaut
    Comme je l'ai marqué plus haut :
    Oui je suis d'accord avec toi mais si je retourne un float je risque une troncation dans le cas ou je travaillerai avec des doubles(par exemple), et si je retourne un double je perds de la "place" pour rien lorsque je travaille avec float, int...
    Ces détails sont peut etre dérisoires mais j'aime faire les choses bien
    C'est sans doute la meilleure solution mais j'aimerais une fonction plus 'générique' (si possible bien entendu )

  8. #8
    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
    Alp t'as donné la seule solution simple que je vois, c-a-d l'utilisation d'un paramètre factice de type T2.

    Si je reprends ton code avec le paramètre factice, celà donne :

    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 T>
    class Vector2D
    {
    public:
    ....
    //ma fonction à spécialiser :
    template<typename T2> static T2 norm(const Vector2D<T> & myVector2D, T2); //fonction statique template permettant de calculer la norme et de retourner le type T2 // avec le paramètre T2 non utilisé.
    };
     
    //declaration de la fonction :
    template<typename T>
    template<typename T2>
    T2 Vector2D<T>::norm(const Vector2D<T> & myVector2D, T2)
    {
    	...//aucun probleme avec la declaration de cette fonction
    }
     
    //specialisation(s) pas nécessaires
    Et tu l'appelles comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    float f = Vector2D<int>::norm( vec, float() ); // la version float
    double d = Vector2D<int>::norm( vec, double() ); // la version double
    Il est impossible pour le compilateur de choisir une spécialisation si tu ne lui indiques pas laquelle, et comme le type de retour n'est jamais pris en compte dans le choix, il faut que tu lui passe un float ou un double ou autre en argument pour lui dire toi même.

  9. #9
    Membre confirmé Avatar de babar63
    Homme Profil pro
    Développeur jeux vidéos/3d Temps réel
    Inscrit en
    Septembre 2005
    Messages
    241
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Développeur jeux vidéos/3d Temps réel

    Informations forums :
    Inscription : Septembre 2005
    Messages : 241
    Par défaut
    J'avais bien pensé à cette solution mais j'ai peur que cela ne fasse pas très 'propre' en tant que programmeur sans doute plus experimenté() que feriez vous? utiliser un parametre bidon pour couvrir tout les cas, ou simplement limiter le retour à un float?

  10. #10
    Membre éprouvé
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 537
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 537
    Par défaut
    personnelement, je differencierait le nom de mes deux fonction, en fonction de la precision voulue.

  11. #11
    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
    Si tu y tiens vraiment, tu peux peut-être écrire un trait qui selon le type sur lequel tu travailles te donne double ou float, mais bon ...
    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
    template <typename NumType>
    struct NormTrait
    {
    typedef double NormType;
    }
     
    template <> struct NormTrait<int>
    {
    typedef float NormType;
    };
     
    template <> struct NormTrait<float>
    {
    typedef float NormType;
    };
     
    // ...
     
    template <typename T>
    NormTrait<T>::NormType Norm(...)
    {
      // ...
    }
    ( cf le tuto dans ma signature : http://alp.developpez.com/tutoriels/traitspolicies/ )

  12. #12
    Membre confirmé Avatar de babar63
    Homme Profil pro
    Développeur jeux vidéos/3d Temps réel
    Inscrit en
    Septembre 2005
    Messages
    241
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Développeur jeux vidéos/3d Temps réel

    Informations forums :
    Inscription : Septembre 2005
    Messages : 241
    Par défaut
    Merci beaucoup pour votre aide je pense que je vais me contenter de retourner un float pour l'instant...
    En tout cas merci beaucoup alp pour le lien ca a l'air vraiment interressant cette histoire de traits et polices je vais essayer de mieux comprendre le principe avant de les utiliser
    Probleme résolu... encore merci

  13. #13
    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
    Et si tu donnais un argument par défaut :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    template<typename T2 = float> static T2 norm(const Vector2D<T> & myVector2D, T2 = float());
    Comme ça tu n'as a préciser que le double() si tu veux plus de précision.

    Perso, je n'utiliserais cette solution que si tu veux vraiment du très générique, mais si tu n'as que la spécialisation pour les float et double à faire, je ferrais deux noms de fonction distincts pour éviter les ambiguités.

    Au passage Policy se traduit par Politique et non Police.

  14. #14
    Membre confirmé Avatar de babar63
    Homme Profil pro
    Développeur jeux vidéos/3d Temps réel
    Inscrit en
    Septembre 2005
    Messages
    241
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Développeur jeux vidéos/3d Temps réel

    Informations forums :
    Inscription : Septembre 2005
    Messages : 241
    Par défaut
    Et si tu donnais un argument par défaut :
    Malheuresement j'ai déjà essayé mais les arguments par default sont seulement autorisés sur les modeles de classe (c'est mon compilateur qui me l'a dit ) Pour l'instant je vais garder mon retour en float je differencierai sans doute plus tard une autre fonction pour les doubles si j'en ai vraiment besoin...
    Au passage Policy se traduit par Politique et non Police
    Merci pour la précision
    Au passage j'aimerais vous posez une question un peu différente, je suis en train de créer une librairie mathematique (comme vous avez peut etre du le constater ) je me demandais si il était possible de regrouper les classes vector2D, vector3D, vector4D au sein d'une meme classe encore plus générique et plus compacte au niveau du code j'ai vu que c'était possible grace aux traits et politiques mais d'après ce que j'en ai retenu pour l'instant il il faut quand meme définir toutes les fonctions donc au niveau du code cela revient aux meme... si cela est possible dans quelle direction dois-je me tourner?
    merci d'avance a bientot

    edit : J'ai oublié de préciser que j'utilisai une structure "T x,y,z" et non un tableau sinon ca aurait été plus simple

  15. #15
    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 peux créer une classe comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    template <typename NumberType, unsigned int Dimension>
    class Vector
    {
    // ...
    };
    et plus loin :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Vector<double, 3> v; // une vecteur de l'espace dont les coord sont des double
    Vector<int, 2> v2; // un vecteur du plan à coordonnées entières
    Vector<float, 1> v3; // un vecteur d'une droite dont les coord sont des float
    Si tu veux implémenter une telle classe, tu peux te servir de boost::array (cf mon tuto sur le sujet). Quand au type que retournera telle ou telle fonction membre (norme et autres), si tu veux être pointilleux, utilise les traits.

    En concevant tout ça de cette manière, tu pourras facilement définir le produit scalaire, et puis utiliser les policies pour définir le produit vectoriel qui ne sera valide que lorsque Dimension vaudra 3.

    Vraiment, lis bien le tuto sur boost::array, celui sur traits et policies, pratique un peu, et tu verras ça pourra te permettre de concevoir quelque chose de bien souple et bien complet.

  16. #16
    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
    D'ailleurs ça me donne une idée d'article sur la conception de telles choses...

  17. #17
    Membre confirmé Avatar de babar63
    Homme Profil pro
    Développeur jeux vidéos/3d Temps réel
    Inscrit en
    Septembre 2005
    Messages
    241
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Développeur jeux vidéos/3d Temps réel

    Informations forums :
    Inscription : Septembre 2005
    Messages : 241
    Par défaut
    D'ailleurs ça me donne une idée d'article sur la conception de telles choses...
    Content d'avoir servi a quelque chose...
    En tout cas merci beaucoup pour ton aide tout ca m'a l'air bien sypathique je vais travailler la dessus...

  18. #18
    Membre confirmé Avatar de babar63
    Homme Profil pro
    Développeur jeux vidéos/3d Temps réel
    Inscrit en
    Septembre 2005
    Messages
    241
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Développeur jeux vidéos/3d Temps réel

    Informations forums :
    Inscription : Septembre 2005
    Messages : 241
    Par défaut
    C'est encore moi......
    J'ai encore une question
    Avant de commencer j'ai essayé de reflechir au moyen d'ajouter des parametres x,y... a mes classes voila un exemple de ce que j'aurais fait pour chacune des classes vecteurs :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    template<typename T>
    class myClass
    {
    public:
    	union {
    		struct { T x,y; };
    		T myArray[2];
    	};
    	myClass();
     
    };
    Ce qui me permettait d'acceder aux valeurs de mes vecteurs par l'intermédiaire des .x, .y ... Malheuresement je n'ai pas trouvé de moyen de transposer cette méthode pour une seule classe générique a tous mes vecteurs... (j'ai commencé a me plonger dans les traits et politiques mais d'après ce que j'en ai retenu pour l'instant ils ne sont pas la pour ca...) bien que ce soit facultatif si quelqu'un a une idée je suis tout prêt à l'entendre.
    Merci d'avance

  19. #19
    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
    Je ne veux pas faire le rabas-joie, mais pour faire ce que tu veux, il faut y aller à grands coups de métaprogrammation (je crois qu'on peut y arriver cependant, pas sûr)... Mais après tout un vecteur en dimension N, c'est simplement un n-uplet, alors pourquoi te prendre la tête avec des x,y,z etc ... ou même a1, a2, ..., an ? Un tableau suffit. Je trouve un boost::array très approprié, cf http://alp.developpez.com/temp/vector.hpp

  20. #20
    Membre confirmé Avatar de babar63
    Homme Profil pro
    Développeur jeux vidéos/3d Temps réel
    Inscrit en
    Septembre 2005
    Messages
    241
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Développeur jeux vidéos/3d Temps réel

    Informations forums :
    Inscription : Septembre 2005
    Messages : 241
    Par défaut
    Comme je l'ai dit c'est facultatif c'était surtout pour connaitre les limites des traits et politiques, j'en était pas sur mais il me semblait bien que ce n'était pas possible avec ces techniques. Je ne suis pas encore sur d'utiliser boost::array j'ai commencé a lire le tuto ca à l'air plutot adapté mais j'aimerais me lancer dans la méta-prog donc je prefere créer mes propres fonctions sur les tableau... histoire d'apprendre...
    Encore merci pour tes conseils...

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. probleme de template
    Par tarang dans le forum Mise en page CSS
    Réponses: 4
    Dernier message: 23/07/2007, 08h17
  2. Map et probleme de template
    Par sleigh dans le forum Langage
    Réponses: 2
    Dernier message: 21/05/2007, 11h04
  3. Map et probleme de template
    Par sleigh dans le forum C++
    Réponses: 2
    Dernier message: 21/05/2007, 11h04
  4. Probleme de template
    Par alexorcet dans le forum Langage
    Réponses: 9
    Dernier message: 30/11/2006, 21h40
  5. [phpBB] Template phpBB et/ou phpLib
    Par corwin dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 2
    Dernier message: 14/02/2006, 15h45

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