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 :

Imiter les generators en C++ : utiliser les pre-processor macros ou les iterables ?


Sujet :

C++

  1. #1
    Membre averti Avatar de Seabirds
    Homme Profil pro
    Post-doctoral fellow
    Inscrit en
    Avril 2015
    Messages
    294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Post-doctoral fellow
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2015
    Messages : 294
    Points : 341
    Points
    341
    Par défaut Imiter les generators en C++ : utiliser les pre-processor macros ou les iterables ?
    Salut à toutes et à tous !
    Je dois générer un gros paquets de combinaisons.
    L'algorithme que j'essaie d'implémenter a été implémenté en Ruby et Python, et tous deux y font l'usage intensif de générateurs (le mignon yield). J'essaie de traduire le code en C++, sauf que les générateurs ne semblent pas supportés par C++.
    Mes recherches sur internet portent sur deux manières de faire (qui sont résumées sur la page Wikipedia, https://en.wikipedia.org/wiki/Genera...mming)#C.2B.2B ).
    La première solution consiste à utiliser une directive macro pour utiliser le mot clé yield. Les exemples wiki sont assez parlant, une implémentation est disponible ici. Cette solution me paraît raisonnablement simple et ne perturbe pas trop le code que je calque. Reproches qui semblent généralement fait : ça ne fait pas trop "C++", et les macros on m'a dit qu'il fallait faire très attention.
    La deuxième solution consiste à utilise le C++11 et les itérables. Avantage apparent, ça semble être plus fidèle à la manière C++ de faire. Au moins sur une exemple simple (celui de wikipedia), ça me semble facile à implémenter.
    Par contre, sachant que mon algorithme est un poil tordu quand même (appel de fonctions récursives, des yield en folie, voir ci-dessous), quelle approche me conseilleriez vous ?

    Cordialement,

    Un échantillon du code en Python (je suis toujours aussi choqué du typage inexistant, en fait ça rend les algos super dur à comprendre )
    Code python : 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
        def f(mu, nu, sigma, n, a):
            if mu == 2:
                yield visit(n, a)
            else:
                for v in f(mu - 1, nu - 1, (mu + sigma) % 2, n, a):
                    yield v
            if nu == mu + 1:
                a[mu] = mu - 1
                yield visit(n, a)
                while a[nu] > 0:
                    a[nu] = a[nu] - 1
                    yield visit(n, a)
            elif nu > mu + 1:
                if (mu + sigma) % 2 == 1:
                    a[nu - 1] = mu - 1
                else:
                    a[mu] = mu - 1
                if (a[nu] + sigma) % 2 == 1:
                    for v in b(mu, nu - 1, 0, n, a):
                        yield v
                else:
                    for v in f(mu, nu - 1, 0, n, a):
                        yield v
                while a[nu] > 0:
                    a[nu] = a[nu] - 1
                    if (a[nu] + sigma) % 2 == 1:
                        for v in b(mu, nu - 1, 0, n, a):
                            yield v
                    else:
                        for v in f(mu, nu - 1, 0, n, a):
                            yield v
    Le débutant, lui, ignore qu'il ignore à ce point, il est fier de ses premiers succès, bien plus qu'il n'est conscient de l'étendue de ce qu'il ne sait pas, dès qu'il progresse en revanche, dès que s'accroît ce qu'il sait, il commence à saisir tout ce qui manque encore à son savoir. Qui sait peu ignore aussi très peu. [Roger Pol-Droit]
    Github
    Mon tout premier projet: une bibliothèque de simulation de génétique des populations

  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 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Ou bien utiliser une classe intermédiaire que tu utilises comme générateur. Et y'a fort à parier que c'est ce qui est sous la logique derrière ceux de Python et consors.
    Une telle classe pourrait avoir une interface du style
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class Generator {
    public:
      Generator(int start, int end) {}
      int next() {}
      bool finished() const {}
    };
    que tu utilises comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Generator g;
    for(int i = g.next(); !g.finished(); i = g.next()) {}
    Tu peux aussi implémenter Generator pour utiliser les itérateurs et utiliser la syntaxe for( int i : g) mais ne l'ayant jamais réalisé je ne connais pas la syntaxe spécifique.
    Parce qu'un générator ça reste un objet qui a un état que l'on interroge et qui change à chaque fois qu'on lui requête la donnée suivante.
    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 expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    739
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

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

    Informations forums :
    Inscription : Juin 2011
    Messages : 739
    Points : 3 627
    Points
    3 627
    Par défaut
    Transformer ce truc en itérateur va être terrible. Les itérateurs sont bien pour les algos qui n'utilisent qu'un seul yield, en gros, où l'on peut extraire une fonction next().

    Le plus simple (en attendant les coroutines) est d'utiliser une fonction de rappel. yield visit(n, a) devient callback(visit(n, a)).
    Niveau utilisation, le code python for n in f(params...): print (n) devient f(params..., [](auto n){ std::cout << n; }); en c++.

  4. #4
    Membre averti Avatar de Seabirds
    Homme Profil pro
    Post-doctoral fellow
    Inscrit en
    Avril 2015
    Messages
    294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Post-doctoral fellow
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2015
    Messages : 294
    Points : 341
    Points
    341
    Par défaut
    Citation Envoyé par jo_link_noir Voir le message
    Transformer ce truc en itérateur va être terrible. Les itérateurs sont bien pour les algos qui n'utilisent qu'un seul yield, en gros, où l'on peut extraire une fonction next().
    Heureux de voir que mon intuition était correcte sur la difficulté à faire une fonction next() dans ce contexte
    Je me renseigne sur les callback, merci encore !
    Le débutant, lui, ignore qu'il ignore à ce point, il est fier de ses premiers succès, bien plus qu'il n'est conscient de l'étendue de ce qu'il ne sait pas, dès qu'il progresse en revanche, dès que s'accroît ce qu'il sait, il commence à saisir tout ce qui manque encore à son savoir. Qui sait peu ignore aussi très peu. [Roger Pol-Droit]
    Github
    Mon tout premier projet: une bibliothèque de simulation de génétique des populations

  5. #5
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Si tu fais du code pour un compilateur particulier, tu peux regarder s'il implémente les coroutines. Sinon, il y a des bibliothèques pour simuler ça, je ne sais pas quel est leur niveau de facilité d'utilisation ou de performance. Par exemple, il y a boost.coroutine.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  6. #6
    Membre averti Avatar de Seabirds
    Homme Profil pro
    Post-doctoral fellow
    Inscrit en
    Avril 2015
    Messages
    294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Post-doctoral fellow
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2015
    Messages : 294
    Points : 341
    Points
    341
    Par défaut
    Après lectures et tutoriels sur les coroutines, j'ai choisi de mettre momentanément de côté cette stratégie des générateurs pour implémenter rapidement la solution bourrine de tout stocker en mémoire (deadline iz coming... )
    Je clos le sujet et publierai le code dès que j'aurais ajouté les routines à l'algo
    Merci à tous pour vos réponses !!!
    Le débutant, lui, ignore qu'il ignore à ce point, il est fier de ses premiers succès, bien plus qu'il n'est conscient de l'étendue de ce qu'il ne sait pas, dès qu'il progresse en revanche, dès que s'accroît ce qu'il sait, il commence à saisir tout ce qui manque encore à son savoir. Qui sait peu ignore aussi très peu. [Roger Pol-Droit]
    Github
    Mon tout premier projet: une bibliothèque de simulation de génétique des populations

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

Discussions similaires

  1. [XL-2007] Macro generation graphe
    Par hellalaboy dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 06/09/2012, 20h43
  2. [PPT-2002] Macro pour generation des graphes
    Par aelmalki dans le forum VBA PowerPoint
    Réponses: 2
    Dernier message: 29/06/2010, 15h08
  3. macros/templates et generation de code
    Par paradize3 dans le forum C++
    Réponses: 3
    Dernier message: 20/11/2007, 08h16
  4. Réponses: 8
    Dernier message: 19/06/2007, 14h45
  5. Generation d'evenements a une date precise
    Par pascalzzz dans le forum MFC
    Réponses: 2
    Dernier message: 04/06/2002, 15h21

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