Publicité
+ Répondre à la discussion Actualité déjà publiée
Page 1 sur 2 12 DernièreDernière
Affichage des résultats 1 à 20 sur 21
  1. #1
    Inactif


    Homme Profil pro Guillaume Belz
    Biochimiste
    Inscrit en
    novembre 2008
    Messages
    5 317
    Détails du profil
    Informations personnelles :
    Nom : Homme Guillaume Belz
    Âge : 38
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Biochimiste
    Secteur : Santé

    Informations forums :
    Inscription : novembre 2008
    Messages : 5 317
    Points : 18 047
    Points
    18 047

    Par défaut Guru Of the Week n° 41 : utiliser la bibliothèque standard

    La bibliothèque standard fournit un nombre important de structures de données et d'algorithmes. Dans de nombreux cas, il est possible de remplacer les structures de contrôle du langage (if, for, while) par les fonctionnalités provenant de celle-ci. Dans ce Guru Of the Week n° 41, Herb Sutter lance le défi de créer un Mastermind en minimisant l'utilisation des structures de contrôle.

    Guru Of the Week n° 41 : utiliser la bibliothèque standard

    Saurez-vous relever le défi et proposer un tel code de Mastermind ?

    Retrouver l'ensemble des Guru of the Week sur la page d'index.

  2. #2
    Membre Expert
    Avatar de mitkl
    Homme Profil pro Timothée Bernard
    Étudiant
    Inscrit en
    février 2010
    Messages
    364
    Détails du profil
    Informations personnelles :
    Nom : Homme Timothée Bernard
    Âge : 23
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : février 2010
    Messages : 364
    Points : 1 088
    Points
    1 088

    Par défaut

    La solution est très intéressante, c'est une approche que je n'avais jamais développé, j'aime beaucoup !

    Citation Envoyé par gbdivers Voir le message
    Saurez-vous relever le défi et proposer un tel code de Mastermind ?
    Honnêtement quand j'ai lu l'énoncé, faire un mastermind sans aucun if/for/while me semblait difficilement réalisable. Après avoir vu la solution, j'ai eu quelques déclics avec l'utilisation de la STL et ça me semble déjà plus réalise.
    Si vous ne savez toujours pas ce qu’est la récursivité, relisez cette phrase.

    Mon blog sur la programmation et l'informatique !

  3. #3
    Membre expérimenté

    Homme Profil pro
    Doctorant en astrophysique
    Inscrit en
    juin 2007
    Messages
    365
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en astrophysique

    Informations forums :
    Inscription : juin 2007
    Messages : 365
    Points : 531
    Points
    531

    Par défaut

    Il manque un lien vers l'article original

    Sinon je trouve dommage que l'exemple de code fourni soit si inutilement cryptique. Ça nuit à la compréhension de l'article, et ça ne fait pas envie (et encore, la mise en forme choisie sur Developpez est un peu plus claire grâce aux sauts de lignes).

  4. #4
    Expert Confirmé Sénior
    Avatar de transgohan
    Homme Profil pro Baptiste ROUSSEL
    Développeur Temps réel Embarqué
    Inscrit en
    janvier 2011
    Messages
    1 757
    Détails du profil
    Informations personnelles :
    Nom : Homme Baptiste ROUSSEL
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Temps réel Embarqué

    Informations forums :
    Inscription : janvier 2011
    Messages : 1 757
    Points : 4 731
    Points
    4 731

    Par défaut

    Je suis pas très calé en c++ mais je vois pas tellement l'intérêt du défi.
    Le but est de n'utiliser que la STL c'est ça ? (après faut bien avouer qu'elle est sous-utilisée - et je me compte dedans xD )
    Car au final, il est faux de dire qu'on n'utilise aucun test et boucle.
    Toujours se souvenir que la majorité des ennuis viennent de l'espace occupé entre la chaise et l'écran de l'ordinateur.

  5. #5
    Membre Expert
    Avatar de mitkl
    Homme Profil pro Timothée Bernard
    Étudiant
    Inscrit en
    février 2010
    Messages
    364
    Détails du profil
    Informations personnelles :
    Nom : Homme Timothée Bernard
    Âge : 23
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : février 2010
    Messages : 364
    Points : 1 088
    Points
    1 088

    Par défaut

    Le but est d'utiliser le moins possible d'if/for/while, c'est un GotW qui fait réfléchir, ça ne veut pas dire qu'il ne faut plus utiliser de structure de contrôle mais au lieu d'imbriquer des if dans des for et compagnie, un petit coup de STL, un foncteur peuvent être plus lisibles.
    Si vous ne savez toujours pas ce qu’est la récursivité, relisez cette phrase.

    Mon blog sur la programmation et l'informatique !

  6. #6
    Membre Expert

    Inscrit en
    mai 2008
    Messages
    1 010
    Détails du profil
    Informations forums :
    Inscription : mai 2008
    Messages : 1 010
    Points : 2 203
    Points
    2 203

    Par défaut

    Citation Envoyé par Kalith Voir le message
    Sinon je trouve dommage que l'exemple de code fourni soit si inutilement cryptique. Ça nuit à la compréhension de l'article, et ça ne fait pas envie
    +1
    Quelle catastrophe ce code... Je ne parle pas de l'utilisation un peu extrême de la STL, qui est après tout le but de l'exercice, mais du reste.
    • Nom de variable courte et cryptique. En quelques lignes on subit du l, M, cm, gm, c, g...
    • Utilisation à outrance de l'opérateur virgule. Sérieux il faut emprisonner le dingo qui s'amuse à écrire des lignes du style return ++cm_[c], ++gm_[toupper(g)], exact_ += c == toupper(g), '.';


    Du reste je crois que bien que le code est buggé. En tout cas chez moi, à chaque nouvel tentative l'affichage du nombre de couleurs correctement devinées est faux car vaut toujours zéro. Par contre l'affichage du nombre de couleurs correctement devinées et bien placées vaut le résultat attendu.

    J'ai l'impression que le problème vient d'ici :

    Code :
    std::transform( comb.begin(), comb.end(), guess.begin(), l.begin(), Count( color, exact ) );
    Sachant que le destructeur de Count effectue des opérations assez complexes (mise à jour de std::map), j'ai l'impression que le code se base sur des détails d'implémentation en supposant que Count sera copié une fois et détruit une fois dans le std::transform mais manque de bol ce n'est pas le cas sur mon compilo.

  7. #7
    Membre expérimenté

    Homme Profil pro
    Doctorant en astrophysique
    Inscrit en
    juin 2007
    Messages
    365
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en astrophysique

    Informations forums :
    Inscription : juin 2007
    Messages : 365
    Points : 531
    Points
    531

    Par défaut

    J'utilise GCC 4.7 sans activer le C++11 (donc pas de sémantique de mouvement, mais le GotW a été écrit avant la sortie de la norme) et sans optimisation, et ça marche correctement chez moi.

    Sinon je rejoins ta critique : la ligne qui m'a fait le plus mal aux yeux est celle que tu as cité.

  8. #8
    Membre du Club
    Homme Profil pro Guillaume Mouton
    Développeur informatique
    Inscrit en
    mars 2012
    Messages
    21
    Détails du profil
    Informations personnelles :
    Nom : Homme Guillaume Mouton
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : mars 2012
    Messages : 21
    Points : 51
    Points
    51

    Par défaut

    Salut,

    Citation Envoyé par Arzar Voir le message
    Utilisation à outrance de l'opérateur virgule. Sérieux il faut emprisonner le dingo qui s'amuse à écrire des lignes du style
    Code :
    return ++cm_[c], ++gm_[toupper(g)], exact_ += c == toupper(g), '.';
    D'ailleurs quelqu'un peut expliquer cette ligne parce que j'ai un peu de mal à voir ce qui est véritablement retourné finalement ?

  9. #9
    Membre expérimenté

    Homme Profil pro
    Doctorant en astrophysique
    Inscrit en
    juin 2007
    Messages
    365
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en astrophysique

    Informations forums :
    Inscription : juin 2007
    Messages : 365
    Points : 531
    Points
    531

    Par défaut

    Seulement le dernier élément, soit ".".
    L'intérêt est de tout écrire en "une instruction", ce qui n'apporte rien en terme de performance, mais peut économiser de la place en terme de quantité de code (c'est discutable ici).

  10. #10
    Membre régulier
    Homme Profil pro Nicolas
    Ingénieur
    Inscrit en
    octobre 2006
    Messages
    41
    Détails du profil
    Informations personnelles :
    Nom : Homme Nicolas
    Âge : 27
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Transports

    Informations forums :
    Inscription : octobre 2006
    Messages : 41
    Points : 77
    Points
    77

    Par défaut

    Grosse déception. Un code "sale" non commenté. Voila qui motive le lecteur a créer sa "propre" solution.

  11. #11
    Membre Expert

    Inscrit en
    mai 2008
    Messages
    1 010
    Détails du profil
    Informations forums :
    Inscription : mai 2008
    Messages : 1 010
    Points : 2 203
    Points
    2 203

    Par défaut

    Je viens de vérifier et le code est effectivement buggé. Il ne marche que si le destructeur du foncteur Count n'est appelé qu'une seule fois dans std::transform, ce qui est effectivement le cas avec gcc 4.7 (car le foncteur n'est copié qu'une fois), mais ce qui n'est pas le cas avec visual studio (où std::transform appelle une fonction helper interne qui copie plusieurs fois le foncteur)

    Du coup, ce n'est pas de chance, mais ce code contrevient là aussi aux bonnes pratiques, en particulier :

    1) Ne pas implémenter de logique complexe dans un destructeur.
    Un destructeur est fait pour nettoyer/libérer des ressources, il n'est pas là pour être le cœur d'un algorithme dans lequel on parcourt et mets à jour des structures complexes.

    2) Ne jamais présager de l'utilisation d'un foncteur par la STL. La règle générale c'est que la STL a le droit de faire ce qu'elle veut d'un foncteur passé à un algo, en particulier elle a le droit de le copier autant de fois que nécessaire.

    Edit :
    Humm, j'ai l'impression que le bug est en fait un peu plus subtil que ça.
    En tout cas si ça marche sous GCC c'est clairement grâce à une optimisation (faite même en debug) qui permet d'éliminer toute copie du foncteur. Il n'y a qu'une seule construction et destruction, du coup on s'assure de toujours bien travailler sur les deux maps membres M cm_, gm_; de la structure Count. Par contre avec VS on a des copies et plusieurs destruction (et le nombre est différent entre le mode debug et release), du coup je n'arrive pas bien à suivre ce qui se passe mais on fini par manipuler une map systématiquement vide...

  12. #12
    Membre du Club
    Homme Profil pro Vincent Ravier
    Développeur informatique
    Inscrit en
    décembre 2011
    Messages
    54
    Détails du profil
    Informations personnelles :
    Nom : Homme Vincent Ravier

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Service public

    Informations forums :
    Inscription : décembre 2011
    Messages : 54
    Points : 59
    Points
    59

    Par défaut

    Je me joins à l'avis général sur la qualité du code... Devoir relire une trentaine de lignes de code plusieurs fois pour les comprendre, gloups.
    En effet, cette ligne
    Code :
    return ++cm_[c], ++gm_[toupper(g)], exact_ += c == toupper(g), '.';
    et en particulier
    Code :
    exact_ += c == toupper(g)
    m'a donné des boutons... Ajouter à un int le résultat d'une comparaison, aïe. Quitte à écrire un code imbitable, un opérateur ternaire pour retourner 0 si false sinon 1 aurait été plus propre:
    Code :
    exact_ += ((c == toupper(g)) == false ? 0 : 1)
    Bref, oui, le problème est solutionné, mais ça sera pas un 20/20!

  13. #13
    Modérateur

    Homme Profil pro Cyrille
    Network programmer
    Inscrit en
    juin 2010
    Messages
    2 201
    Détails du profil
    Informations personnelles :
    Nom : Homme Cyrille
    Âge : 27
    Localisation : France

    Informations professionnelles :
    Activité : Network programmer

    Informations forums :
    Inscription : juin 2010
    Messages : 2 201
    Points : 5 721
    Points
    5 721

    Par défaut

    Citation Envoyé par vravier Voir le message
    Ajouter à un int le résultat d'une comparaison, aïe. Quitte à écrire un code imbitable, un opérateur ternaire pour retourner 0 si false sinon 1 aurait été plus propre:
    Code :
    exact_ += ((c == toupper(g)) == false ? 0 : 1)
    Bref, oui, le problème est solutionné, mais ça sera pas un 20/20!
    Question de point de vue, mais le type bool existe bien en C++ et est considéré comme un entier pouvant prendre 2 valeurs, 0 pour faux ou 1 pour vrai. Les transtypages sont implicites et fonctionnent, c'est correctement normé (par rapport au C à ce niveau).
    cf le prochain curriculum low level.

    Ca peut sembler à moitié de l'obfuscation, mais c'est correct.

  14. #14
    Membre du Club
    Homme Profil pro Vincent Ravier
    Développeur informatique
    Inscrit en
    décembre 2011
    Messages
    54
    Détails du profil
    Informations personnelles :
    Nom : Homme Vincent Ravier

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Service public

    Informations forums :
    Inscription : décembre 2011
    Messages : 54
    Points : 59
    Points
    59

    Par défaut

    Citation Envoyé par Bousk Voir le message
    Ca peut sembler à moitié de l'obfuscation, mais c'est correct.
    Bien sur c'est correct, mais comme beaucoup d'autres choses en C/C++, c'est pas parce que ça peut se faire, que c'est forcément bien de le faire
    Sur ce point bien particulier, je trouve juste que ça clarifie en écrivant concrètement ce que ça doit faire. Comme par exemple la fonction GetCheck() sur les checkbox de la MFC qui retourne 0, 1 ou 2 (pas cochée, cochée, à moitié cochée), et qu'on veut en récupérer un booléen, je préfère écrire
    Code :
    bool value = dialog.GetCheck() != 0;
    plutot que
    Code :
    bool value = dialog.GetCheck();
    Les 2 sont corrects et compilent, c'est juste une question d'appréciation personnelle

  15. #15
    Modérateur

    Homme Profil pro Cyrille
    Network programmer
    Inscrit en
    juin 2010
    Messages
    2 201
    Détails du profil
    Informations personnelles :
    Nom : Homme Cyrille
    Âge : 27
    Localisation : France

    Informations professionnelles :
    Activité : Network programmer

    Informations forums :
    Inscription : juin 2010
    Messages : 2 201
    Points : 5 721
    Points
    5 721

    Par défaut

    Sauf que ton exemple est à l'envers.
    Tu veux juste transformer une information entière en bool.
    L'exemple du GotW fait l'inverse : il transforme un bool en entier. Et là il n'y a pas besoin de fiorutire, ni d'opérateur ternaire, la conversion est implicite en C++.

  16. #16
    Membre du Club
    Homme Profil pro Vincent Ravier
    Développeur informatique
    Inscrit en
    décembre 2011
    Messages
    54
    Détails du profil
    Informations personnelles :
    Nom : Homme Vincent Ravier

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Service public

    Informations forums :
    Inscription : décembre 2011
    Messages : 54
    Points : 59
    Points
    59

    Par défaut

    Comme tu le dis, la conversion est implicite, je parlais simplement du fait d'expliciter les choses pour une lecture plus directe du code, rien de plus Mais je le répète, ce n'est qu'un avis personnel!

  17. #17
    Inactif


    Homme Profil pro Guillaume Belz
    Biochimiste
    Inscrit en
    novembre 2008
    Messages
    5 317
    Détails du profil
    Informations personnelles :
    Nom : Homme Guillaume Belz
    Âge : 38
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Biochimiste
    Secteur : Santé

    Informations forums :
    Inscription : novembre 2008
    Messages : 5 317
    Points : 18 047
    Points
    18 047

    Par défaut

    Ecrire " == false" (ou true) est inutilement verbeux. Mais on est tous d'accord pour dire que ce code est obscure. Personnellement, j'utilise très peu l'opérateur "virgule", sauf cas particulier (plusieurs initialisation ou incrémentation dans une boucle for par exemple)

    Il ne faut pas oublier que ce code date de quelques années quand même

    Finalement, l'idée est proche de ce dont je parle en début d'année Faut-il bannir le for du C++ ?, ça reste un exercice intéressant pour apprendre la lib standard

  18. #18
    Expert Confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    décembre 2008
    Messages
    805
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : décembre 2008
    Messages : 805
    Points : 2 650
    Points
    2 650

    Par défaut

    Citation Envoyé par Kalith Voir le message
    Seulement le dernier élément, soit ".".
    L'intérêt est de tout écrire en "une instruction", ce qui n'apporte rien en terme de performance, mais peut économiser de la place en terme de quantité de code (c'est discutable ici).
    Pourquoi? Parce que le ";\r\n" (pour windows, naturellement) pèse plus lourd dans le code source que ", " ?

    Personnellement, je me pose aussi la question de l'intérêt de cette ligne-ci:
    Code :
    1
    2
    3
     
    srand( time(0) ),
                generate( comb.begin(), comb.end(), ChoosePeg );
    Dû à une vieille habitude, je lis toujours le code du main avant le reste (et donc, je déclare toujours les classes et structures pour en placer les définitions après l'endroit où elles sont utilisées, mais c'est juste une habitude) et j'ai tellement bloqué sur cette ligne bizarre que je n'ai pas vu la ligne du return

    Je trouve regrettable de faire du code qui économise la place, et encore pire dans une publication dont l'objectif est d'expliquer aux gens. Eventuellement, on à là une excellente explication de comment rendre un code illisible, mais à part ça...

    Je sais que les GotW sont célèbres, et nombre de ces articles de bonne qualité, mais là, je me demande si il est pertinent de ne pas proposer une solution propre et lisible en tant que "NdT" (note du traducteur) parce que si quelqu'un commence C++ et tombe sur ce... hum... truc, je parie qu'il changera immédiatement de langage!
    Ce serait dommage, puisque je pense que le but est d'expliquer la puissance et la lisibilité de la STL... non?

    Notez que c'est peut-être aussi dû au fait que je sois trop idiot pour le comprendre facilement...

    PS: a noter que je ne dénigre absolument pas le travail du traducteur, j'indiquais simplement que je pense qu'il est contre-productif de publier la traduction exacte dans ce cas précis, si on souhaite faire la promotion de C++ et faire oublier une partie de la réputation de complexité dont il souffre, et que cet article justifie parfaitement (non mais, sérieux, l' "opérator,()" pour s'en servir pour séparer des instructions, il faut vraiment avoir l'esprit tordu...)

    PPS: @gbdivers: désolé de ne pas avoir le temps de participer à la rubrique d'où sort ce travail, mon projet personnel est plutôt chrono-phage ...

  19. #19
    Membre expérimenté

    Homme Profil pro
    Doctorant en astrophysique
    Inscrit en
    juin 2007
    Messages
    365
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en astrophysique

    Informations forums :
    Inscription : juin 2007
    Messages : 365
    Points : 531
    Points
    531

    Par défaut

    Citation Envoyé par Freem Voir le message
    Pourquoi? Parce que le ";\r\n" (pour windows, naturellement) pèse plus lourd dans le code source que ", " ?
    On est d'accord, c'est du chipotage (quoi que tu ne comptes pas les caractères nécessaires à l'indentation de la nouvelle ligne )... À mon avis c'est plutôt pour se donner bonne conscience et passer outre la "règle" selon laquelle on doit toujours sauter une ligne après un point virgule, mais rarement après une virgule.

    Sinon je suis d'accord avec toi, mais c'est toujours délicat d'apporter des corrections aussi importantes dans une traduction. La question se pose d'ailleurs aussi avec l'arrivée du C++11, qui pourrait simplifier/résoudre certains problèmes qui sont traités par les GotW ou autres articles.

  20. #20
    Expert Confirmé Sénior
    Avatar de Luc Hermitte
    Homme Profil pro Luc Hermitte
    Développeur informatique
    Inscrit en
    août 2003
    Messages
    4 734
    Détails du profil
    Informations personnelles :
    Nom : Homme Luc Hermitte
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : août 2003
    Messages : 4 734
    Points : 7 784
    Points
    7 784

    Par défaut

    Je ne vois pas de réaction à la solution d'HS là où la solution fut initialement donnée: http://groups.google.com/group/comp....a506b0d2dd86a7 (ne pas oublier que les GOTW étaient des "énigmes" posées sur clc++m)

    En revanche, la solution a été corrigée dans MXC++.

    Pour moi trois choix sont possibles dans la mesure où je considère qu'une traduction ne doit en aucun cas altérer le contenu ou le message de ce qui est traduit:
    - ne pas traduire ce GOTW
    - demander à l'auteur la permission de reprendre le code qui se trouve dans MXC++.
    - signaler en note de bas de page que le code est en fait buggué et qu'il faudrait externaliser les tableaux qui se trouvent dans Count pour lever le bug.

    La solution 2 est préférable (et bien sûr), il faudra préciser d'où vient en fait la solution.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •