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

C++ Discussion :

enum et string


Sujet :

C++

  1. #1
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut enum et string
    Je souhaite faire quelque chose comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    enum myenum {
    e_str1,
    e_str2,
    e_str3,
    e_end
    };
     
    const char  *mystr[e_end]={
    "str1",
    "str2",
    "str3",
    };
    ...mais en évitant de coder tout deux fois, c-à-d de créer manuellement une entrée dans mystr pour chaque enum créé. Quand la liste d'enum s'allonge les erreurs deviennent fréquentes. Bref, si le compilateur avait un support de ce genre se serait pas mal:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    const char *AskComplierToConvertEnumToString(myenum e_str)
    {
    return substr(charof(e_str),2,0xffffffff);
    }
    Une solution serait une générateur de code, mais bon...
    D'autres solutions ?
    Merci.

  2. #2
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    Boost.Preprocessor peut te permettre de factoriser ce genre de chose :
    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
     
    #include <boost/preprocessor.hpp>
     
    // la liste unique où positionner les différentes valeurs
    #define LISTE_CHAINES\
       (str1)\
       (str2)\
       (str3)\
       (str4)\
       (str5)\
       (str6)\
     
    // macro pour definir l'enum
    #define DEFINIR_ENUM(unused_1,unused_2,elem) BOOST_PP_CAT(e_,elem),
    // macro pour definir les chaines de caractères
    #define DEFINIR_CHAINES(unused_1,unused_2,elem) BOOST_PP_STRINGIZE(elem),
     
    // definition de l'enum
    enum myenum {
       BOOST_PP_SEQ_FOR_EACH(DEFINIR_ENUM,~,LISTE_CHAINES)
       e_end
    };
    // definition du tableau de chaines
    const char  *mystr[e_end]={
       BOOST_PP_SEQ_FOR_EACH(DEFINIR_CHAINES,~,LISTE_CHAINES)
    };
    // undef de ce dont on n'a plus besoin
    #undef DEFINIR_CHAINES
    #undef DEFINIR_ENUM
    #undef LISTE_CHAINES

  3. #3
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    J'en suis tout baba
    Avec un peu d'astuce les compilos permettent donc pas mal de choses. Les opérateurs # et ## dans les define sont bien connus, mais la simulation de boucle for ou de code conditionnel if dans les define m'épate (note, il semble qu'on soit limité à 256 dans la liste, mais ça devrait suffire; s'il le faut il suffit de "compléter" les macros de boost).

    Mais ce qui m'épate le plus c'est peut-être bien votre capacité à répondre au quart de tour à une question tout de même très spécialisée (enfin, il me semble) en pointant directement sur l'outil qui résoud le problème "l'air de rien".

    Merci.

  4. #4
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Bon, voilà, j'aimerais aller un peu plus loin maintenant, mais je cale. J'aimerais définir une structure qui serait un prototype d'un ensemble de structures qui ne seraient différenciées que par LISTE_CHAINES.
    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
    struct MonType
    {
    #define DEFINIR_ENUM(unused_1,unused_2,elem) BOOST_PP_CAT(e_,elem),
     enum myenum {
       BOOST_PP_SEQ_FOR_EACH(DEFINIR_ENUM,~,LISTE_CHAINES)
       e_end
    };
    #define DEFINIR_CHAINES(unused_1,unused_2,elem) BOOST_PP_STRINGIZE(elem),
    static const char  *mystr[e_end]={
       BOOST_PP_SEQ_FOR_EACH(DEFINIR_CHAINES,~,LISTE_CHAINES)
    };
    ...
    MonType();
    ~MonType();
    void foo1();
    void foo2();
    ...
    };
    Je ne vois pas comment templatiser cela. Exemple:
    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
    struct LesNoms
    {
     enum myenum {
       e_prenom,
       e_nom;
       e_end
    };
    static const char  *mystr[e_end]={"prenom","nom"};
    ...
    LesNoms();
    ~LesNoms();
    void foo1();
    void foo2();
    ...
    };
     
    struct LesComms
    {
     enum myenum {
       e_tel,
       e_fax;
       e_email;
       e_end
    };
    static const char  *mystr[e_end]={"tel","fax","email"};
    ...
    LesComms();
    ~LesComms();
    void foo1();
    void foo2();
    ...
    };
    J'aurais ainsi de nombreuses structures qui ne diffèrent que par myenum et mystr.

    Merci.

  5. #5
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    Rien ne t'empêche d'enchaîner les traitements dans les macros de Boost.Preprocessor (liste de liste). Cependant, à terme, cela risque de devenir assez illisible et assez indébuggable
    Au passage, pourquoi ne pas ajouter mystr comme variable statique de MonType ? Il semblerait d'après ce que tu montres qu'il soit cohérent de les regrouper, non ?

    [EDIT] Arg,
    J'ai répondu à côté... Une piste serait probablement de sortir ton enum et ta chaîne dans une classe trait, d'ajouter un enum pour les différents types et de faire ta classe générique avec cet enum et la classe trait associée.

  6. #6
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Oui, mystr est static bien sûr. Le code est incomplet/imparfait/incorrect, il est là pour illustrer ma demande.

    Donc, tu proposes une classe de traits pour chaque couple [myenum,mystr] à passer en paramètre d'un template. J'essaie ça (mais i'm faut un truc à shooter mes neurones d'abord - i'manque la tasse de café ou le retroussage de manches dans la liste de smiley - )

  7. #7
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Et bien voilà, magnifico, tout baigne
    Tous mes enums associés aux char const * sont isolés dans des structs, des "traits" quoi !
    Ensuite j'ai une classe template qui gère de façon commune tous ces traits, sauf que j'ai 2 manières différentes de les traiter. J'ai donc créé deux autres template, genre "policies" avec des prédicats associés (ou plutôt des foncteurs).

    A l'instantiation j'ai un code du genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	TraitementCommun< TraitementA<EnumX> > les_colonnes;
    	TraitementCommun< TraitementB<EnumY> > les_lignes;
    A l'usage ça donne (les AssignMachin sont les foncteurs)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    les_lignes.Set(id1, AssignLine<EnumY>(EnumY::e_str1, value1));
    les_colonnes.Set(id2, AssignColumn<EnumX>(EnumX::e_str2, value2, subvalue2));
    Voilà, voilà je sais, ça ne vous dit rien sans le code complet, mais je suis fier de moi quand même
    Encore merci !

  8. #8
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut

    Bienvenu dans le monde mystérieux de la programmation générique

Discussions similaires

  1. Réponses: 3
    Dernier message: 12/06/2015, 14h05
  2. Enum et String
    Par Gurdil le nain dans le forum VB.NET
    Réponses: 8
    Dernier message: 18/04/2011, 15h57
  3. Enum de strings
    Par lasrevinu dans le forum C#
    Réponses: 13
    Dernier message: 07/04/2010, 13h57
  4. [Java 5] Enum et String
    Par ebaynaud dans le forum Langage
    Réponses: 8
    Dernier message: 10/01/2008, 17h09
  5. un enum de string
    Par dalio2579 dans le forum C#
    Réponses: 6
    Dernier message: 15/05/2007, 12h15

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