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 :

Problème de compilation avec les traits (g++)


Sujet :

Langage C++

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 47
    Points : 36
    Points
    36
    Par défaut Problème de compilation avec les traits (g++)
    Bonjour à tous,

    J'essaye de déclarer une fonction fill() comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    template <typename T>
    void fill(T* image);
    Je tente d'implémenter la fonction de la manière suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    template <typename T>
    void AVPictureAdapter::fill(T* image) {
     
    }
     
    template <typename U>
    void AVPictureAdapter::fill< BSPF_IMAGE::Image<U> >(BSPF_IMAGE::Image<U>* image) {
     
    }
    Le problème est que la deuxième version ne fonctionne pas, j'ai l'erreur suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    AVPictureAdapter.t:9:80: erreur: function template partial specialization ‘fill<BSPF_IMAGE::Image<T> >’ is not allowed
    AVPictureAdapter.t:9:6: erreur: prototype forvoid BSPF_FFMPEGIO::AVPictureAdapter::fill(BSPF_IMAGE::Image<T>*)’ does not match any in class ‘BSPF_FFMPEGIO::AVPictureAdapter’
    AVPictureAdapter.h:39:12: erreur: candidates are: template<class T> void BSPF_FFMPEGIO::AVPictureAdapter::fill(T*)
    AVPictureAdapter.h:31:12: erreur:                 void BSPF_FFMPEGIO::AVPictureAdapter::fill(BSPF_FFMPEGIO::PixelFormat_t, uint8_t*, int, int)
    AVPictureAdapter.h:26:12: erreur:                 void BSPF_FFMPEGIO::AVPictureAdapter::fill(BSPF_IMAGE::ImageType, BSPF_UTILS::bspf_buffer*)
    Ma question est donc comment spécialiser une classe de traits avec un template et non un type/une classe standard ?

    Merci d'avance

  2. #2
    Membre éprouvé

    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 533
    Points : 1 086
    Points
    1 086
    Par défaut
    Il me semble qu'on ne peut pas spécialiser partiellement une méthode.
    Il faut passer par une struct/class intermédiaire :
    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
     
    namespace detail {
    	template <typename ITEM>
    	struct Filler {
    		static inline void fill(ITEM* item);
    	};
     
    	template <typename TYPE>
    	struct Filler<BSPF_IMAGE::Image<TYPE>> {
    		static inline void fill(BSPF_IMAGE::Image<TYPE>* image) {
    		}
    	};
    }
     
    template <typename T>
    void AVPictureAdapter::fill(T* item) {
    	detail::Filler<T>::fill(item);
    }

  3. #3
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 626
    Points : 30 684
    Points
    30 684
    Par défaut
    Salut,

    De manière générale, on ne peut effectivement pas faire une spécialisation partielle sur une fonction...

    Par contre, il est possible (si tant est que ça ait un sens ) se surcharger une fonction template, dont une des surcharge serait template
    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
     
    /* une version qui utilise "n'importe quel type" */
    template <typename Type>
    void foo(Type const & t)
    {
        /* ce qui doit etre fait */
    }
    /* ici, on va surtout fournir un type pour spécifier le type à appliquer à
     *  BSPF_IMAGE::Image<U>
     */
    template <typename U>
    void foo( BSPF_IMAGE::Image<U> const & img)
    {
        /* ce qui doit etre fait */
    }
    /* et ici, on va travailler sur un type bien précis */
    void foo(MonTypeParticulier const & img )
    {
        /* ce qui doit etre fait */
    }
    Pour ce qui est des fonctions membres de classes template, le problème est que la surcharge a rarement de sens, étant donné que l'on va généralement travailler sur des types dépendant des paramètres template utilisés.

    Avoir une classe proche 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
    template <typename T>
    class MaClass
    {
        public:
            template <typename Type>
            void foo(Type const & t)
            {
                /* ce qui doit etre fait */
            }
     
            template <typename U>
            void foo( BSPF_IMAGE::Image<U> const & img)
            {
                /* ce qui doit etre fait */
            }
     
            void foo(MonTypeParticulier const & img )
            {
                /* ce qui doit etre fait */
            }
    };
    N'aura sans doute pas le moindre intérêt, ne serait-ce que parce qu'il n'y a aucune corrélation entre le T fourni à la classe et les différents type utilisés comme paramètres des fonctions

    Il y a donc deux solutions :

    Soit on crée une spécialisation (partielle ou totale) de l'ensemble de la classe:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    /* une classe utilisant "n'importe quel type" */
    template <typename T>
    class MyClass
    {
        /* tout ce qui doit exister pour la version générique */
    };
    /* la meme classe utilisant un type particulier */
    template <>
    class MyClass<MyParticularType>
    {
        /* tout ce qui doit exister pour la version générique */
    };
    Soit on peut déléguer une partie du travail à une classe template dont la responsabilité est réduite, et qui sera (totalement ou partiellement) spécialisée:
    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 T>
    class MySubClass
    {
    };
    template <>
    class MySubClass<MyParticularType>
    {
     
    };
    template <typename T>
    class MyClass
    {
        public:
        /* le plus simple, et le plus lisible, c'est de passer par un typedef */
        typedef MySubClass<T> subclass_type;
        void foo()
       {
           subclass_type sub;
           sub.doSomething();
           /* OU OU OU, si c'est une fonction statique */
           subclass_type::doSomething();
       }
    };
    Le choix qu'il y a à faire entre le fait de créer la classe que j'ai appelée MySubClass sous la forme d'une classe imbriquée ou non dépendant essentiellement de l'utilité cette classe peut avoir dans le projet

    Il est souvent préférable d'envisager la deuxième solution si la classe qui a besoin de ce genre de mécanisme est relativement complexe : tu auras sans doute beaucoup plus facile spécialiser (partiellement ou totalement) une classe ayant une responsabilité limitée plutôt que de devoir spécialiser de la même manière une classe ayant une responsabilité complexe
    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

  4. #4
    Membre chevronné
    Avatar de Joel F
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2002
    Messages
    918
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2002
    Messages : 918
    Points : 1 921
    Points
    1 921
    Par défaut
    On peut aussi préférer l'utilisation d'un Objet Fonction Polymorphe basé sur le protocole result_of

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 47
    Points : 36
    Points
    36
    Par défaut
    Merci beaucoup pour vos réponses.

    Je vais tester. J'hésite beaucoup entre vos solutions, mais je crois que je vais choisir celle de koala01 pour sa simplicité syntaxique (mon code donnant déjà assez mal à la tête les jours où je ne suis pas en forme lol). D'ailleurs, ton hypothèse était bonne, c'est effectivement une fonction template dans une classe non template .

    Je vais tester et passer en "résolu" si ça marche comme sur des roulettes .

    @Joel F : j'avoue ne pas savoir ce que c'est, mais ça m'a l'air bien compliqué pour la chose que je veux faire ^^.

    Merci encore.

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

Discussions similaires

  1. Probléme de compilation avec les structures
    Par bambitous dans le forum C
    Réponses: 3
    Dernier message: 17/12/2012, 09h40
  2. Réponses: 1
    Dernier message: 16/07/2008, 02h34
  3. Réponses: 4
    Dernier message: 18/12/2007, 21h54
  4. Problème de compilation avec Dev-C++
    Par Rouliann dans le forum Dev-C++
    Réponses: 14
    Dernier message: 14/06/2004, 18h44
  5. Réponses: 1
    Dernier message: 29/10/2003, 12h16

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