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 :

creer une macro paramètrée


Sujet :

Langage C++

  1. #1
    Membre éclairé Avatar de PadawanDuDelphi
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2006
    Messages
    678
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : Bâtiment

    Informations forums :
    Inscription : Août 2006
    Messages : 678
    Points : 717
    Points
    717
    Par défaut creer une macro paramètrée
    Bonjour à tous,

    Je bloque sur un problème dont je ne suis pas sûr qu'une solution existe.
    Voilà, nous avons des classes générée automatiquement avec des conteneurs et des itérateurs spécifiques. Afin de parcourir tous les éléments, nous avons créé une macro qui prend en paramètre le nom de la classe, le nom du conteneur et qui va appeler un visiteur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    #define ITERATE_OVER_COLLECTION(_className, _collectionName, _featureName, _value) \
        { \
            _className::_collectionName##_iterator it = _value->_collectionName().begin(), ite = _value->_collectionName().end(); \
            for(;it!=ite;++it) \
            { \
                it->_featureName()->acceptVisitor(this); \
            } \
        }
    J'aimerais maintenant pouvoir modifier le code acceptVisitor() par d'autres méthodes. Par exemple pour supprimer un élément de la collection.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    ...
    if (_value == (&(it->_FeatureName.get())) )\
    {\
    _value->_featureName().erase(it);\
    it->_featureName()->acceptVisitor(this); \
    
    }\
    Est-il possible de paramétrer une macro pour faire cela ? A moins que notre approche soit complètement bancale et qu'il existe des techniques appropriée en c++ ?

    ++,
    Nicolas.
    For crying out loud !

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 965
    Points
    32 965
    Billets dans le blog
    4
    Par défaut
    Bonsoir,

    "paramétrer" une macro, ça n'a pas grand sens.
    Si tu veux faire autre chose, tu crées une autre macro ?
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Membre éclairé Avatar de PadawanDuDelphi
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2006
    Messages
    678
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : Bâtiment

    Informations forums :
    Inscription : Août 2006
    Messages : 678
    Points : 717
    Points
    717
    Par défaut
    Merci Bousk,

    Effectivement il semblerait que ce soit l'unique moyen. Je voulais éviter de dupliquer du code simplement pour rajouter une ligne dans la macro mais cela ne semble pas possible en effet.

    La conception à partir d'une macro n'est peut-être pas la bonne solution, mais je ne vois pas d'autres moyen.

    Merci encore pour ton aide !
    For crying out loud !

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

    Informations professionnelles :
    Activité : aucun

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

    Et si tu faisais, tout simplement, varier ton visiteur

    Tu crées une classe de base (abstraite) visitor , qui se mariera très bien avec la fonction accept, puis tu dérive tes visiteurs en fonction de ce que tu veux qu'ils fassent : l'un enlève les éléments, l'autre compare telle ou telle donnée, le troisième offre le café à ces dames etc.

    Il ne faut pas aller plus loin que ça
    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

  5. #5
    Membre éclairé Avatar de PadawanDuDelphi
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2006
    Messages
    678
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : Bâtiment

    Informations forums :
    Inscription : Août 2006
    Messages : 678
    Points : 717
    Points
    717
    Par défaut
    Oui Effectivement c'est une très bonne idée.
    Le problème que j'ai c'est que les méthodes liées à accept prennent les même paramètres que la macro (typiquement pour ajouter un élément il me faut un lien sur l'iterateur en cours, soit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    _className::_collectionName##_iterator it
    Et donc encore une macro pour chaque visiteur.

    Par contre je me suis inspiré de ton idée, j'ai ajouter une variable enum (REMOVE, ADD, MAKE_COFFEE)...)qui me permet (via un switch..case) de paramétrer ma macro.
    La classe de base reste abstraite, et chaque classe dérivée à juste à switcher sur la bonne bonne valeur de l'enum.

    Ce n'est pas très maintenable à mon sens, mais ça reste transparent et simple d'utilisation pour le codeur lambda qui utilisera ces visiteurs.

    Thanks again !
    For crying out loud !

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 965
    Points
    32 965
    Billets dans le blog
    4
    Par défaut
    Pourquoi avoir une macro pour chaque visiteur ?
    Il te suffit de passer en paramètre de la macro le visiteur à utiliser.
    Tu peux même passer les paramètres spécifiques au visiteur, via l'excellent __VA_ARGS__
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    Citation Envoyé par PadawanDuDelphi Voir le message
    Oui Effectivement c'est une très bonne idée.
    Le problème que j'ai c'est que les méthodes liées à accept prennent les même paramètres que la macro (typiquement pour ajouter un élément il me faut un lien sur l'iterateur en cours, soit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    _className::_collectionName##_iterator it
    Et donc encore une macro pour chaque visiteur.

    Par contre je me suis inspiré de ton idée, j'ai ajouter une variable enum (REMOVE, ADD, MAKE_COFFEE)...)qui me permet (via un switch..case) de paramétrer ma macro.
    La classe de base reste abstraite, et chaque classe dérivée à juste à switcher sur la bonne bonne valeur de l'enum.

    Ce n'est pas très maintenable à mon sens, mais ça reste transparent et simple d'utilisation pour le codeur lambda qui utilisera ces visiteurs.

    Thks again !
    Et encore!!!

    L'énorme avantage des visiteurs, c'est qu'il s'agit de classes ou de structures.

    Cela signifie que tu peux parfaitement envisager de fournir un membre ou l'autre à chaque visiteur, en fonction de tes propres besoins

    Il n'y a, par exemple, rien qui t'interdise d'avoir un visiteur proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class MonVisiteurConcret : public Visiteur{
        public:
            MonVisiteurConcret(std::vector<Type*>::const_iterator const & it):
            it(it){}
            void visit(TypeDerive1 const &);
            void visit(TypeDerive2 const &);
            /* ... */
            void visit(TypeDeriveN const &);
        private:
            std::vector<Type*>::const_iterator const & it;
    };
    qui serait utilisé sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for(auto it =tab.begin(); it!=tab.end();++it){
        MonVisiteurConcret v(it);
        (*it)->accept(v);
    }
    ou un autre qui prendrait la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class AutreVisiteurConcret : public Visiteur{
        public:
            AutreVisiteurConcret (std::vector<Type*> & tab, std::vector<Type*>::const_iterator const & it ):
            tab(tab), it(it){}
            void visit(TypeDerive1 const &);
            void visit(TypeDerive2 const &);
            /* ... */
            void visit(TypeDeriveN const &);
        private:
            std::vector<Type*> tab;
            std::vector<Type*>::const_iterator const & it;
    };
    qui serait utilisé sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    for(auto it =tab.begin(); it!=tab.end();++it){
        AutreVisiteurConcret v(tab, it);
        (*it)->accept(v);
    }
    Le premier se contente de manipuler l'itérateur s'il en a besoin, le second est en mesure de modifier le tableau si c'est ce qu'il est sensé faire
    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

Discussions similaires

  1. [XL-2003] Creer une macro pour application demo
    Par revemane dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 10/04/2009, 15h31
  2. [A-03] Creer une macro sur Access
    Par khongo agon dans le forum IHM
    Réponses: 1
    Dernier message: 27/11/2008, 17h37
  3. Creer une macro excel de recherche?
    Par doogybreton dans le forum Macros et VBA Excel
    Réponses: 22
    Dernier message: 06/12/2007, 14h42
  4. Creer une macro de comparaison ?
    Par gregounnet dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 24/07/2007, 17h42
  5. Creer Une Macro Gros Classeur
    Par Sting dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 16/07/2007, 20h51

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