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] petit probleme d'instanciation


Sujet :

Langage C++

  1. #21
    Membre chevronné

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2013
    Messages : 610
    Points : 1 878
    Points
    1 878
    Billets dans le blog
    21
    Par défaut

    Une possibilité en utilisant SFINAE pour tester si la classe est abstraite pendant l'exécution (il me semble que c'était ce que tu demandais):

    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 <class T>
    struct Test {
      typedef T type;
      Test(int) { create(); }
      void create() { new T(); }
    };
     
    template <class T>
    void test_if_abstract( Test<T>::type ) {}
    template <class T>
    void test_if_abstract( ... ) { throw 1; }
     
    int main() {
      test_if_abstract<ConcreteBase>(10);
      test_if_abstract<AbstractBase>(10);
    };
    ça compile sur un compilateur même pas C++98 (le borland gratuit, un ancêtre tout petit
    et ça envoie une exception à l'exécution.


    non, il y a une erreur dans mon code, dsl

  2. #22
    Membre expérimenté
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 562
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 562
    Points : 1 313
    Points
    1 313
    Par défaut
    excuse moi mais je sais pas ce que c'est que l'ast de compilation lol
    IKEAS : Finalement je crois que c'est dans ses faiblesses que l'on y trouve a la fois de la force et a la fois de la richesse...
    ----------------------------------------------------
    Si vous avez du taf en wpf & design d'application sympa, contactez moi !!!!
    http://ultimatecorp.eu/wpf/

  3. #23
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2014
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2014
    Messages : 345
    Points : 1 211
    Points
    1 211
    Par défaut
    Ce n'est pas ce qu'il demande, il veut un booléen constexpr pour l'utiliser avec un template, afin de faire des spécialisations.
    Peu d'intérêt à déterminer si une classe est abstraite à l'exécution d'ailleurs, puisque si le code est correct (et utilisable concrètement) il n'est pas censé compiler ...

  4. #24
    Membre chevronné

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2013
    Messages : 610
    Points : 1 878
    Points
    1 878
    Billets dans le blog
    21
    Par défaut
    "ce que j'aimerais juste savoir c'est si on peut faire une compilation conditionnelle sur un Template en fonction du type
    ou autoriser quand même la compilation et résoudre le problème au runtime avec un try/catch par exemple"

    si, semble-t-il, ce serait une des questions posées...

  5. #25
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2014
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2014
    Messages : 345
    Points : 1 211
    Points
    1 211
    Par défaut
    Ok j'avais pas vu, autant pour moi.

    Bon sinon sous gcc il y a ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    template <typename T>
    	struct is_abstract {
    		enum { value = __is_abstract(T) };
    	};
    D'après la doc https://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html
    M'enfin, c'est dégueu.

  6. #26
    Membre expérimenté
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 562
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 562
    Points : 1 313
    Points
    1 313
    Par défaut
    allez louya ca marche impec

    merci encore

    pour info je colle le code complet

    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
     
    template<typename T>
    struct is_abstract3 {
            enum {
                    value = __is_abstract(T)
            };
    };
     
    // Factory to create T, lives in a struct to allow default template parameters
    template<typename T, int ABSTRACT = is_abstract3<T>::value>
    struct Create3 {
            static T* create() {
                    std::cout << "Create Class : " << typeid(T).name() << "\n";
                    return new T();
            }
    };
     
    // specialize Create for abstract base classes
    template<typename T>
    struct Create3<T, 1> {
            static T* create() {
                    std::cout << "Cannot create and Abstract Base Class!\n";
                    std::cout << " Create failed on type_info::name() = "
                                    << typeid(T).name() << "\n";
                    return 0;
            }
    };
    et en execution
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     Create3<Alpha>::create();
     Create3<IBase>::create();
    IKEAS : Finalement je crois que c'est dans ses faiblesses que l'on y trouve a la fois de la force et a la fois de la richesse...
    ----------------------------------------------------
    Si vous avez du taf en wpf & design d'application sympa, contactez moi !!!!
    http://ultimatecorp.eu/wpf/

  7. #27
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Par contre, maintenant, ton code ne compile plus qu'avec gcc, et dans certaines de ses versions seulement.

    C'est peut-être dommage.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  8. #28
    Membre expérimenté
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 562
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 562
    Points : 1 313
    Points
    1 313
    Par défaut
    je peux éventuellement mettre des directives de compilation avec std:is_abstract que j'ai essayé par ailleurs sur visual studio
    et qui marche aussi en c++11

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    template<typename T>
    struct is_abstract3 {
    	enum {
    		value = std::is_abstract<T>::value
    	};
    };
    IKEAS : Finalement je crois que c'est dans ses faiblesses que l'on y trouve a la fois de la force et a la fois de la richesse...
    ----------------------------------------------------
    Si vous avez du taf en wpf & design d'application sympa, contactez moi !!!!
    http://ultimatecorp.eu/wpf/

  9. #29
    Membre expérimenté
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 562
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 562
    Points : 1 313
    Points
    1 313
    Par défaut
    juste une petite question connexe

    je ne sais pas si c'est possible de passer du code suivant
    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
     
    template<typename T>
    struct is_abstract3 {
            enum {
                    value = __is_abstract(T)
            };
    };
     
    // Factory to create T, lives in a struct to allow default template parameters
    template<typename T, int ABSTRACT = is_abstract3<T>::value>
    struct Create3 {
            static T* create() {
                    std::cout << "Create Class : " << typeid(T).name() << "\n";
                    return new T();
            }
    };
     
    // specialize Create for abstract base classes
    template<typename T>
    struct Create3<T, 1> {
            static T* create() {
                    std::cout << "Cannot create and Abstract Base Class!\n";
                    std::cout << " Create failed on type_info::name() = "
                                    << typeid(T).name() << "\n";
                    return 0;
            }
    };
    qui fait la sélection sur la classe

    et faire un code qui ferrait la sélection sur un membre de la classe
    un peut dans ce style

    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
     
    class Create5 {
    public:
            template<typename T, int ABSTRACT = __is_abstract(T)>
            static T* create() {
                    std::cout << "Create Class : " << typeid(T).name() << "\n";
                    return new T();
            };
            template<typename T, 1>
                    static T* create() {
                            std::cout << "Cannot create and Abstract Base Class!\n";
                                    std::cout << " Create failed on type_info::name() = "
                                                    << typeid(T).name() << "\n";
                                    eturn 0;
                    };
     
     
    };
    évidement ce code ne passe pas
    IKEAS : Finalement je crois que c'est dans ses faiblesses que l'on y trouve a la fois de la force et a la fois de la richesse...
    ----------------------------------------------------
    Si vous avez du taf en wpf & design d'application sympa, contactez moi !!!!
    http://ultimatecorp.eu/wpf/

  10. #30
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2014
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2014
    Messages : 345
    Points : 1 211
    Points
    1 211
    Par défaut
    Tu ne peux pas spécialiser partiellement une fonction.
    En revanche tu peux déplacer ta fonction create() dans une structure à part, que tu pourras spécialiser.

    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, bool = __is_abstract(T)>
    struct create_helper {
      static T* create () { return new T(); }
    };
     
    template <typename T>
    struct create_helper<T, 1> {
      static T* create () { /* ... */ }
    };
     
    class Create {
    public:
      template <typename T>
        static T* create() {
          return create_helper<T>::create();
        }
    };

  11. #31
    Membre expérimenté
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 562
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 562
    Points : 1 313
    Points
    1 313
    Par défaut
    et si je veux définir le corps des fonction en dehors des structures ?

    j'ai tenté cela mais ça passe pas
    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
    30
    31
    32
    33
     
    template<typename T, bool = __is_abstract(T)>
    struct create_helper2 {
            static T* create();
    };
     
    template<typename T, bool = __is_abstract(T)>
    T* create_helper2<T,bool>::create(){
            std::cout << "Create Class : " << typeid(T).name() << "\n";
                            return new T();
    }
     
    template<typename T>
    struct create_helper2<T, 1> {
            static T* create();
    };
     
    template<typename T>
    T* create_helper2<T, 1>::create(); {
            std::cout << "Cannot create and Abstract Base Class!\n";
                            std::cout << " Create failed on type_info::name() = "
                                            << typeid(T).name() << "\n";
            return 0;
    }
     
     
    class Create6 {
    public:
            template<typename T>
            static T* create() {
                    return create_helper2<T>::create();
            }
    };
    IKEAS : Finalement je crois que c'est dans ses faiblesses que l'on y trouve a la fois de la force et a la fois de la richesse...
    ----------------------------------------------------
    Si vous avez du taf en wpf & design d'application sympa, contactez moi !!!!
    http://ultimatecorp.eu/wpf/

  12. #32
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2014
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2014
    Messages : 345
    Points : 1 211
    Points
    1 211
    Par défaut
    C'est normal. Ton code est incorrect. Relis-le, il ne veut rien dire.
    Renseigne-toi sur la définition d'un membre de classe template.

  13. #33
    Membre expérimenté
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 562
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 562
    Points : 1 313
    Points
    1 313
    Par défaut
    oui je tente mais c'est la spécialisation qui me pose problème
    je sais pas trop comment exprimer le bool pour la version instanciable et pour exprimer le 1 dans la version abstraite

    sur les versions simple j'y arrive
    IKEAS : Finalement je crois que c'est dans ses faiblesses que l'on y trouve a la fois de la force et a la fois de la richesse...
    ----------------------------------------------------
    Si vous avez du taf en wpf & design d'application sympa, contactez moi !!!!
    http://ultimatecorp.eu/wpf/

  14. #34
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2014
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2014
    Messages : 345
    Points : 1 211
    Points
    1 211
    Par défaut
    Le bool = __is_abstract(T) ça déclare un paramètre sans nom. Pour dire, en gros, "j'ai un deuxième paramètre, booléen, qui vaut par défaut __is_abstract(T), mais pour ce cas d'usage, je me fiche de savoir comment s'appelle ce paramètre, vraiment. Ce qui m'importe c'est la valeur".
    Maintenant si tu as besoin d'utiliser ce booléen il n'y a qu'à lui donner un nom.

  15. #35
    Membre expérimenté
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 562
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 562
    Points : 1 313
    Points
    1 313
    Par défaut
    non non j'en ai pas vraiment besoin du bool
    je vois juste pas comment écrire les deux formats
    et quand j'utilise le refactoring d'eclipse il se plante aussi

    voila ce a quoi j'arrive

    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
     
    template <typename T, bool U = __is_abstract(T)>
    struct create_helper4 {
      static T* create ();
    };
     
    template <typename T, bool U>
    T* create_helper4<T, U>::create(){
            std::cout << "create on create_helper4 \n";
            return new T();
    }
     
    template<typename T>
    struct create_helper4<T, 1> {
            static T* create();
    };
     
    template<typename T>
    T* create_helper4<T, 1>::create() {
            std::cout << "Cannot create and Abstract Base Class!\n";
                            std::cout << " Create failed on type_info::name() = "
                                            << typeid(T).name() << "\n";
            return 0;
    }
    la ca passe
    par contre je sais pas comment supprimer le U de la premiere struct
    IKEAS : Finalement je crois que c'est dans ses faiblesses que l'on y trouve a la fois de la force et a la fois de la richesse...
    ----------------------------------------------------
    Si vous avez du taf en wpf & design d'application sympa, contactez moi !!!!
    http://ultimatecorp.eu/wpf/

  16. #36
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2014
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2014
    Messages : 345
    Points : 1 211
    Points
    1 211
    Par défaut
    Donc ça fonctionne maintenant ?

  17. #37
    Membre expérimenté
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 562
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 562
    Points : 1 313
    Points
    1 313
    Par défaut
    oui ça marche mais
    tu aurais pas une solution pour passer de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    template <typename T, bool U = __is_abstract(T)>
    à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    template <typename T, bool  = __is_abstract(T)>
    car si j’enlève le U
    je n'arrive plus à faire la définition pour (enfin ça ne compile plus)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    T* create_helper4<T, U>::create()
    IKEAS : Finalement je crois que c'est dans ses faiblesses que l'on y trouve a la fois de la force et a la fois de la richesse...
    ----------------------------------------------------
    Si vous avez du taf en wpf & design d'application sympa, contactez moi !!!!
    http://ultimatecorp.eu/wpf/

  18. #38
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    mais pourquoi veux-tu enlever le U.
    Tu peux le renommer en abstractness, isAbstract, bidule ou ce que tu veux, mais en supprimant le nom, tu ne pourras pas le donner à create_helper4.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  19. #39
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2014
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2014
    Messages : 345
    Points : 1 211
    Points
    1 211
    Par défaut
    Si tu enlèves le U, tu mets quoi entre les chevrons <> pour la spécialisation ?
    Tu n'as pas d'autre choix ici que donner un nom à ta variable pour passer sa valeur.

  20. #40
    Membre expérimenté
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 562
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 562
    Points : 1 313
    Points
    1 313
    Par défaut
    en fait je n'ai pas vraiment besoin de récupérer la valeur
    je trouvais que la syntaxe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    template <typename T, bool = __is_abstract(T)>
    était plus "sexy"

    j'ai la solution mais je pensais que ça serait plus simple de spécialiser le template sans définir le nom de la variable
    après c'est peut être pas possible
    IKEAS : Finalement je crois que c'est dans ses faiblesses que l'on y trouve a la fois de la force et a la fois de la richesse...
    ----------------------------------------------------
    Si vous avez du taf en wpf & design d'application sympa, contactez moi !!!!
    http://ultimatecorp.eu/wpf/

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 3 PremièrePremière 123 DernièreDernière

Discussions similaires

  1. Petit problème de fork
    Par osmose22 dans le forum Linux
    Réponses: 7
    Dernier message: 18/03/2007, 21h10
  2. [TP]petit probleme avec solution
    Par pompompolom dans le forum Turbo Pascal
    Réponses: 1
    Dernier message: 02/12/2004, 19h48
  3. petit probleme avec l'éditeur de builder
    Par qZheneton dans le forum C++Builder
    Réponses: 2
    Dernier message: 28/10/2004, 16h19
  4. petit probleme de requete
    Par nico33307 dans le forum Décisions SGBD
    Réponses: 2
    Dernier message: 25/08/2004, 11h36
  5. petit probleme dans une requte POSTGRE SQL
    Par ghis le fou dans le forum Requêtes
    Réponses: 5
    Dernier message: 08/09/2003, 13h51

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