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 :

Template et Polymorphisme = contrainte ?


Sujet :

Langage C++

  1. #1
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut Template et Polymorphisme = contrainte ?
    Bonjour à tous,

    Je me pose une petite question existentielle !
    Est-ce que le fait d'avoir une classe template avec des fonctions virtuelles ajoutent trop de contraintes au client...

    Exemple avec cette class Camera:
    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
    template <typename T>
    class Camera {
    public:
    	typedef typename T value_type; //Accès au type depuis l'extérieur
    	typedef typename vigra::BasicImage<T> image; //Accès au type depuis l'extérieur
     
    	Camera(std::string nomCamera);
    	virtual ~Camera() {}
    	Camera (const & Camera); // On interdit la copie
     
    	virtual image LoadImageByNumber(int number) = 0;
    	virtual image LoadImageByTime(double time);
     
    protected:
    	double m_Tech; // Période d'échantillonnage de la caméra
    	const std::string m_NomCamera;
    };
    Le client devra désormais utiliser le polymorphisme, non pas par un simple pointeur Camera *, mais bien par un Camera<T> * ....

    Celà représente t-il une contrainte forte ? Trop forte?
    Ce que je veux dire par là c'est que l'introduction d'un template est pour moi une souplesse de plus pour un changement éventuel pour la suite... Si c'est vraiment super chiant pour les appelants (il vont devoir tout templater en fait dans l'IHM), alors je laisse tomber...

    d'éclaicir ma lanterne !

  2. #2
    Membre actif 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 : 37
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 241
    Points : 207
    Points
    207
    Par défaut
    Bonjour, ce n'est que mon avis mais je ne vois pas en quoi cela represente une contrainte. Pour un projet spécifique tu peux toujours utiliser un typedef (e.g : typedef Camera<float> Cameraf) si la notation "dérange". Ensuite ta classe sera réutilisable si tu as besoin d'une camera qui cette fois doit gérer n'importe quel type. Je pense qu'en comparaison de tout ce que peut apporter les templates la notation est peu cher payée... Mais encore une fois ce n'est que mon avis
    - hp pavillon dv7
    - intel(R) Core(TM)2 Duo CPU P8400 @ 2.26GHz 2.27GHz
    - nVidia GeForce 9600M GT
    - mémoire vive : 3.0Go

  3. #3
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    OK d'accord. C'est vrai qu'on gagne en souplesse. Mais je me demande si c'est vraiment ce que je cherche. Je m'explique.
    Car si je veux quelquechose de dynamique à l'éxécution je suis marron.
    Je peux pas avoir un conteneur de Camera<T>, qui mélange double et int par exemple.

  4. #4
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Voilà une citation de Koala qui semble aller dans mon sens. Ou bien alors j'ai rien compris...
    Citation Envoyé par Koala01
    Or le mécanisme meme des template empeche la virtualisation des méthodes (tu pourrait *éventuellement* utiliser le CRTP, par contre mais, en vaut-ce réellement la peine )

  5. #5
    Membre actif 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 : 37
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 241
    Points : 207
    Points
    207
    Par défaut
    Je le comprend plutot dans le sens ou "est-il vraiment necessaire d'utiliser le polymorphisme sur les templates?" Il y aura toujours des exceptions bien sur mais en regle général je pense que travailler sur un type (float,...) pour un projet spécifique est suffisant. Si vraiment tu as besoin de ce genre de container tu peux toujours definir une classe de base pour caméra et ensuite la stocker dans le container cette classe...
    - hp pavillon dv7
    - intel(R) Core(TM)2 Duo CPU P8400 @ 2.26GHz 2.27GHz
    - nVidia GeForce 9600M GT
    - mémoire vive : 3.0Go

  6. #6
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Camera, c'est déjà ma classe de base abstraite. La faire dériver d'une autre classe ne servirait à rien puisque je ne pourrais alors pas appeller les fonctions membres virtuelles qui m'intéressent (qui elles sont template)
    Hum... ça devient embetant tout ça...

  7. #7
    Membre actif 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 : 37
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 241
    Points : 207
    Points
    207
    Par défaut
    Oui en effet j'ai sauté une étape dans le code désolé, dans ce cas non je suppose que tu ne pourra pas avoir de conteneur de ce genre (je ne vois pas vraiment ce qu'est la CRTP donc je peux me tromper). Mais comme tu l'as dit tu gagne en souplesse, maintenant si on retourne la question admettant que tu banisse les templates, qu'est ce que tu y gagnes vraiment?
    - hp pavillon dv7
    - intel(R) Core(TM)2 Duo CPU P8400 @ 2.26GHz 2.27GHz
    - nVidia GeForce 9600M GT
    - mémoire vive : 3.0Go

  8. #8
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    http://en.wikipedia.org/wiki/Curious...mplate_Pattern

    J'attend juste quelque temps des fois que j'aie une réponse qui soulève un problème que j'avais pas vu ...
    Et après je mettrai

  9. #9
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Sinon je pourrai toujours templater la fonction en question, et pas la classe:
    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
     
    class Camera {
    public:
    	Camera(std::string nomCamera);
    	virtual ~Camera() {}
    	Camera (const & Camera); // On interdit la copie
     
            template <typename T>
    	virtual image<T> LoadImageByNumber(int number) = 0;
            template <typename T>
    	virtual image<T> LoadImageByTime(double time);
     
    protected:
    	double m_Tech; // Période d'échantillonnage de la caméra
    	const std::string m_NomCamera;
    };
    C'est à étudier, j'y avais pas pensé...

  10. #10
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Non, on ne peut pas faire de fonction virtuelle "plus template que sa classe".
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  11. #11
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Effectivement... +1

  12. #12
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    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
    class CameraBase
    {
    public:
    	virtual image LoadImageByNumber(int number) = 0;
    	virtual image LoadImageByTime(double time) = 0;
    };
     
    template <typename T>
    class CameraImpl : public CameraBase
    {
    public:
    	typedef typename T value_type; //Accès au type depuis l'extérieur
    	typedef typename vigra::BasicImage<T> image; //Accès au type depuis l'extérieur
     
    	CameraImpl (std::string nomCamera);
    	virtual ~CameraImpl () {}
    	CameraImpl (const & CameraImpl ); // On interdit la copie
     
    	virtual image LoadImageByNumber(int number) = 0;
    	virtual image LoadImageByTime(double time);
     
    protected:
    	double m_Tech; // Période d'échantillonnage de la caméra
    	const std::string m_NomCamera;
    };
     
    typedef CameraImpl<float> Camera;
    Non ?

  13. #13
    Membre actif 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 : 37
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 241
    Points : 207
    Points
    207
    Par défaut
    Non ?
    C'est ce que je pensais aussi mais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef typename vigra::BasicImage<T> image;
    image est defini selon un template....

    Merci pour le lien poukill vraiment....Curieux ce pattern en effet mais ca a l'air interessant
    - hp pavillon dv7
    - intel(R) Core(TM)2 Duo CPU P8400 @ 2.26GHz 2.27GHz
    - nVidia GeForce 9600M GT
    - mémoire vive : 3.0Go

  14. #14
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    J'ai envie de te dire, et alors ? Ca n'a aucun rapport.

    En passant ces 2 typenames sont inutiles à premiere vue.

  15. #15
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Non.

    Citation Envoyé par NiamorH Voir le message
    J'ai envie de te dire, et alors ? Ca n'a aucun rapport.
    Si car la surcharge que tu me proposes, si attirante quelle doit n'est pas valide. Voir l'entrée ICI de la FAQ. La fonction LoadImage revoit une image qui doit dépendre du type en cours. Le type 'image' que tu as utilisé n'était pas valable.

    En passant ces 2 typenames sont inutiles à premiere vue.
    Si si, ils le sont -> voir ICI
    Enfin l'utilisation de typename est conseillé.

    Merci en tous cas de vous pencher sur mon problème, qui n'est, il faut bien le dire, pas si facile que ça à comprendre...

  16. #16
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    Tes deux liens sont identiques, je suppose que tu parlais de ce lien là : http://cpp.developpez.com/faq/cpp/?p...LATES_typename

    Mais dans ce cas, je pense que tu te trompes sur l'utilisation de typename.

    Citation Envoyé par C++ Templates : The Complete Guide
    The typename prefix to a name is required when the name :

    1. Appears in a template
    2. Is qualified
    3. Is not used as in a list of base class specifications or in a list of member initializers introducing a constructor definition
    4. Is dependent on a template parameter


    Furthermore, the typename prefix is not allowed unless at least the first three previous conditions hold.
    Dans ton cas, ces deux typename sont bien inutiles : ils ne respectent pas la condition N°4.
    Je suis même étonné que tu compile car typedef typename T value_type; n'est pas qualified (condition 2) et donc ce typename devrait être interdit !

    Pour le type image retourné, tu as tout à fait raison, j'étais à la masse. Je regarderais en détail plus tard. Cela poserait un problème de faire une classe de base pour les image que tu retournerais par pointeur ?

  17. #17
    Membre confirmé

    Inscrit en
    Août 2007
    Messages
    300
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 300
    Points : 527
    Points
    527
    Par défaut
    Je suis désolé, j'ai du mal à comprendre la question. Les librairies C++ sont maintenant pratiquement toutes templates, sans problème particulier d'utilisation (j'utilise STL, Boost et CGAL, et il n'y a pratiquement rien qui soit non template dans ces libs très courantes).
    Faire des conteneurs mixtes se fait classiquement en dérivant d'une classe de base non template. L'appel des fonctions virtuelles marche très bien (je ne comprends pas l'histoire "le mécanisme meme des template empeche la virtualisation des méthodes"). Les méthodes virtuelles sont bien sûr disponible dans les classes template (ou alors de quoi parle-t-on? que vient faire la dérivation du type paramètre dans l'histoire?). Si le type de retour d'une fm template est inconnu dans la classe de base, il suffit d'appliquer la même méthode (type de retour template dérivant aussi d'une classe de base), comme ceci:
    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
     
    struct   image_base  { virtual void              affiche (void ) const { throw ( "ne pas appeler directement" ); } };
    struct   camera_base { virtual const image_base& image  ( void ) const { throw ( "ne pas appeler directement" ); } };
     
    template <typename T> struct image_derive : public image_base {
    virtual void affiche (void ) const { cout << "affiche derive(" << typeid ( T ).name() <<")\n"; } };
     
    template <typename T> struct camera_derive : public camera_base {
    virtual const image_derive<T>& image ( void ) const { return ( img ); }
    image_derive<T> img;
    };
     
    int main ..
    {
    vector<camera_base *>  vb;
     
        vb.push_back ( new camera_derive<int>() );
        vb.push_back ( new camera_derive<float>() );
     
        vb[0]->image().affiche();
        vb[1]->image().affiche();
    }
    En ce qui me concerne, la classe telle qu'exprimée dans le premier post me conviendrait totalement en tant qu'utilisateur, j'ai bien du mal à voir de quelle limitation réelle on parle dans la totalité de ce fil de discussion. Ou alors le code ci-dessus n'est pas standard? (j'utilise pourtant des choses de ce genre un peu partout en BCB 2007 et VS 2008, on peut pas vraiment parler de compilateur exotique - et de toute façon, je crois bien que dans le standard, un résolution de signature de fonction virtuelle est validée moyennant la covariance par types de base, et non par la correspondance stricte).
    "Maybe C++0x will inspire people to write tutorials emphasizing simple use, rather than just papers showing off cleverness." - Bjarne Stroustrup
    "Modern C++11 is not your daddy’s C++" - Herb Sutter

  18. #18
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Citation Envoyé par NiamorH Voir le message
    Tes deux liens sont identiques, je suppose que tu parlais de ce lien là : http://cpp.developpez.com/faq/cpp/?p...LATES_typename

    Mais dans ce cas, je pense que tu te trompes sur l'utilisation de typename.
    Efftivement... Y'en a un sur les deux qui était inutile...

    Citation Envoyé par ac_wingless Voir le message
    Je suis désolé, j'ai du mal à comprendre la question. Les librairies C++ sont maintenant pratiquement toutes templates, sans problème particulier d'utilisation (j'utilise STL, Boost et CGAL, et il n'y a pratiquement rien qui soit non template dans ces libs très courantes).
    Ton code est correct et fonctionne bien. J'utilise la librairie VIGRA qui ne possède pas de classe de base pour les images, tout est templaté ! Je suis donc coincé pour ce type d'approche, car il me faut un type de retour covariant...

    De toute façon, je pense que je ne suis pas dans le vrai... Je m'explique :
    La classe Camera a pour seule but d'être une classe de base. Les autres classes CameraIR, CameraVisible etc... implémentent les fonctions membres qui vont bien pour aller chercher des images sur un serveur distant.

    Les caméras peuvent être monochromatiques, ou bien RGB, ce qui fait donc deux formats très différents! Mais les types sont connus à l'avance !
    C'est pourquoi j'ai un:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    class CameraVisible : public Camera <vigra::RGB <double> > {...}
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    class CameraIR : public Camera <vigra::UInt16> {...}
    Vais aller réfléchir encore un peu...

  19. #19
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Points : 1 051
    Points
    1 051
    Par défaut
    Efftivement... Y'en a un sur les deux qui était inutile...
    Heu... les deux. Le fait que vigra::BasicImage<T> désigne un type de dépend pas du paramètre template T, c'est toujours le cas, il n'y a pas d'ambiguité.


    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
    namespace vigra
    {
      template <class T>  
      class BasicImage1
      {
     
      };
    }
     
    template <class T>  
    class BasicImage2
    {
     
    };
     
    template <class T>
    class C
    {
      typedef typename vigra::BasicImage1<T> image1; // Inutile mais compile
      typedef vigra::BasicImage1<T> image2; // Compile
     
      //typedef typename BasicImage2<T> image3; // Interdit car pas qualified
      typedef BasicImage2<T> image4; // Compile
    };
     
    int main()
    {
      C<int> c;
    }

  20. #20
    Membre confirmé

    Inscrit en
    Août 2007
    Messages
    300
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 300
    Points : 527
    Points
    527
    Par défaut
    Citation Envoyé par poukill Voir le message
    J'utilise la librairie VIGRA qui ne possède pas de classe de base pour les images, tout est templaté !
    Ah d'accord... la technique ci-dessus ne va donc pas marcher directement, il faudrait de l'habillage pas trop beau (renvoyer une classe template contenant un vigra::BasicImage<T>, et dérivant d'une base comme dans le post ci-dessus).

    Du point de vue du titre de la discussion, je pense que l'utilisation des templates elle-même n'introduit pas de contrainte particulière (cf. technique du post ci-dessus), mais par contre le besoin de conteneurs hétérogènes force à des contorsions qui, tout en étant obligatoires (et donc tolérées) dans certains langages, sont fondamentalement inélégantes.
    "Maybe C++0x will inspire people to write tutorials emphasizing simple use, rather than just papers showing off cleverness." - Bjarne Stroustrup
    "Modern C++11 is not your daddy’s C++" - Herb Sutter

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

Discussions similaires

  1. probleme template et polymorphisme
    Par thenewby dans le forum Langage
    Réponses: 9
    Dernier message: 16/07/2012, 16h48
  2. templates et polymorphisme
    Par mister3957 dans le forum C++
    Réponses: 9
    Dernier message: 01/04/2009, 16h59
  3. template et polymorphisme
    Par new.proger dans le forum Langage
    Réponses: 14
    Dernier message: 28/08/2007, 00h35
  4. Template et polymorphisme
    Par fabienpot dans le forum Langage
    Réponses: 9
    Dernier message: 07/09/2006, 16h32
  5. Template et polymorphisme
    Par Pierre_IPROS dans le forum Langage
    Réponses: 19
    Dernier message: 09/10/2005, 23h04

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