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 :

Une fonction virtuelle ne peut pas retourner un template!


Sujet :

Langage C++

  1. #1
    Membre expérimenté
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Points : 1 452
    Points
    1 452
    Par défaut Une fonction virtuelle ne peut pas retourner un template!
    Bonjour,

    le code suivant, avec GCC, ne compile pas:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class A
    {
        public:
            template <class T>
            virtual T ma_fonction()
            {
                return T();
            }
    };
    Y'a-t-il un moyen de le compiler?

    Sinon, y'a t'il un moyen de choper un type, sans le connaitre à la compilation?
    Ex:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    type_of(Ma_fonction_qui_retourne_un_pointeur_de_type_au_hasard) item;
    Mon idée était de faire des conteneurs qui contenaient des types, pour pouvoir ensuite utiliser ces types. Mais il semble que ce ne soit pas possible...

    Merci!

  2. #2
    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, une fonction virtuelle ne peut pas être plus template que sa classe... Donc ça ne compilera pas !

    Peut être une solution avec des classes de trait ?

  3. #3
    Membre expérimenté
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Points : 1 452
    Points
    1 452
    Par défaut
    Ca m'interesse...
    Tu peux préciser?

  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
    J'ai pas mieux que ça pour l'instant :
    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
     
    template <int> struct Type 
    {
    	typedef int Promote;
    };
     
    template <>
    struct Type <0>
    {
    	typedef double Promote;
    };
     
    template <>
    struct Type <1>
    {
    	typedef unsigned char Promote;
    };
     
    template <>
    struct Type <2>
    {
    	typedef float Promote;
    };
     
    int main()
    {
    	Type<0>::Promote a;   
    }
    A bien y réfléchir, ça me paraît difficile de faire mieux...

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

    Informations professionnelles :
    Activité : aucun

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

    Non seulement, une fonction ne peut pas être plus template que la classe dans laquelle elle se trouve, mais, en plus, une fonction template ne peut pas être virtualisée (ou, dans l'autre sens, une fonction virtuelle ne peut pas être templatée )

    En effet, le type utilisé dans une fonction template est déterminé à la compilation, alors que le type utilisé dans une fonction virtuelle est déterminé... à l'exécution

    Tu peux donc, selon ta situation propre, te tourner vers une gestion à base de traits et de politiques (en cherchant bien, tu trouvera un tuto écrit par Alp qui traite des traits et des politiques sur le site ), ou t'organiser en vue de mettre en place un retour co-variant, voire, un opérateur de convertion.

    Maintenant, si tu souhaites avoir plus de précision quant à ce qu'il te faut choisir, il faudra nous en écrire un peu plus
    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

  6. #6
    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
    Non seulement une fonction virtuelle ne peut pas être template, mais surtout une résolution d'appel de fonction (même non virtuelle) ne peut pas se faire sur le type de retour. Sans savoir quel est le but du code il est difficile de proposer des alternatives.

    Pour ce qui est de "faire des conteneurs qui contenaient des types, pour pouvoir ensuite utiliser ces types", il s'agit des conteneurs hétérogènes, pour lesquels de nombreux outils existent.
    - Par exemple Boost::any lorsqu'on veut autoriser absolument tout type possible sans restriction, ou
    - Boost::variant lorsqu'on a une liste finie (et courte) de types possibles.
    - Quand toutes les classes du conteneur peuvent dériver d'une même classe de base, on peut bien sûr stocker un pointeur de la classe de base dans le conteneur.
    - Si ce pointeur doit lui même renvoyer un pointeur virtuel, on peut propager l'indirection, 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
    struct outil_base           { virtual void              utilise      ( void ) const { throw; } };
    struct protege_outil_base   { virtual const outil_base& deverrouille ( void ) const { throw; } };
     
    template < class T > class outil : public outil_base {
        virtual void utilise ( void ) const { cout << "utilise outil " << typeid ( T ).name() <<"\n"; } };
    template < class T > class protege_outil : public protege_outil_base { outil<T> o;
        virtual const outil_base& deverrouille ( void ) const { return ( o ); } };
     
    void f ...
    {
    vector<protege_outil_base * > v;
     
        v.push_back ( new protege_outil<int>() );
        v.push_back ( new protege_outil<std::string>() );
     
        v[0]->deverrouille().utilise();
        v[1]->deverrouille().utilise();
    Vu le nombre de discussions similaires ces dernières semaines, je me demande s'il ne faudrait pas rajouter une rubrique à la FAQ. Peut être vaut-il mieux attendre la sortie du TR1 sous Visual Studio 2008, je me demande s'ils ne proposent pas des outils standards pour ça.
    "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

  7. #7
    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
    Il faudrait déjà que les forumeurs lisent les faqs.

  8. #8
    Membre expérimenté
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Points : 1 452
    Points
    1 452
    Par défaut
    Ok je vais expliquer mon problème

    Déjà, premier point, toutes mes structures dérivent de MF_Base.

    Donc j'ai une classe qui gère les MF_Base:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    class MF_Boss : public MF_Base
    {
         public:
              list <MF_Base *> elements;
    };
    Moi, ce que je voudrais, c'est étant donnés plusieurs types (que j'aurais stockés), c'est pouvoir faire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    MF_Boss::fonction(conteneur_de_type cont)
    {
        for(int i = 0; i < cont.size(); i++)
            elements.push_back(new typeof(cont[i].type()));
    }
    C'est possible?

  9. #9
    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 coyotte507 Voir le message
    C'est possible?
    Si les types du conteneur sont eux aussi tous dérivés de MF_Base, en ajoutant une fonction membre virtuelle clone à MF_Base, et en envoyant un tableau d'objets hétérogènes correspondant aux types souhaités.
    Si les types sont totalement sans connection ni classe de base commune, et en plus inconnaissables au stade de l'écriture, il faudra attendre l'arrivée de C++09, qui introduit les template variadiques ainsi que les tuple (c'est conçu pour pouvoir écrire un printf à la fois sûr, et sans limitation de type).
    "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

  10. #10
    Membre expérimenté
    Avatar de coyotte507
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    1 327
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 327
    Points : 1 452
    Points
    1 452
    Par défaut
    Maintenant que j'y réfléchis, grace au code que tu m'as proposé, je peux faire ça:
    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
    class MF_Base
    {
      ....
    };
     
    class MF_Surf : public MF_Base
    {
      ....
    };
     
    struct protege_outil_base   { virtual MF_Base* deverrouille ( void ) const { throw; } };
     
    template < class T > class protege_outil : public protege_outil_base { typedef T mytype;
        virtual MF_Base* deverrouille ( void ) { return dynamic_cast<MF_Base *> (new mytype); } };
     
    void f ...
    {
    vector<protege_outil_base * > v;
     
        v.push_back ( new protege_outil<MF_Base>() );
        v.push_back ( new protege_outil<MF_Surf>() );
     
        MF_Base *elem1 = v[0]->deverrouille();
        MF_Base *elem2 = v[1]->deverrouille();
    }
    Ca me permet de faire exactement ce que je veux!
    Merci beaucoup
    Je regrette pas d'avoir exposé mon problème

  11. #11
    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
    Ca parait plus logique oui.
    Maintenant, pour deverouille, un static_cast aurait suffit je pense.

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

Discussions similaires

  1. Réponses: 9
    Dernier message: 08/08/2016, 15h52
  2. Réponses: 3
    Dernier message: 29/01/2008, 16h17
  3. Executer une fonction dans un module pas encore importe
    Par Aragorn_destroy dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 20/06/2007, 14h21
  4. Réponses: 3
    Dernier message: 06/03/2007, 14h15
  5. Réponses: 2
    Dernier message: 05/03/2006, 19h29

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