Salut user019.
Ce n'est pas machin mais Winston Churchill qui est l'auteur de la phrase suivante :
@+La démocratie est le pire des régimes - à l'exception de tous les autres déjà essayés dans le passé.
Salut user019.
Ce n'est pas machin mais Winston Churchill qui est l'auteur de la phrase suivante :
@+La démocratie est le pire des régimes - à l'exception de tous les autres déjà essayés dans le passé.
Si vous êtes de mon aide, vous pouvez cliquer sur .
Mon site : http://www.jcz.fr
vous avez tout dit, mais ce qui est plus compliqué est que programmation générique a toujours été une casse tête pour les développeurs qui dorme beaucoup, oui l'évolution du c++11\14 en fait un peu trop, mais son évolution vient bien sûr changer et faciliter ce qui était autre foi une casse tête. je suis encore étudiant et mes amis me déteste quand g fait du c++, mais je pense que java lui n'a fait l'histoire que parce qu'il est simplicité de c++ mais son niveau ne change pas, la question que je me pose est: "jusqu'où les objets?"
www.stlport.org/resources/StepanovUSA.htmlEnvoyé par A. Stepanov
Oui. Mais à titre personnel, je préfère std::optional ou équivalent.
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
Pour moi c'est justement ce genre de chose ( std::optional ) qui rends le C++ compliqué et va a l'encontre même du KISS, c'est juste rajouter encore et encore des couches qui rendent le C++ une montagne de fonction tout plus utiles et inutiles que les autres.
Je comprends le principe d'une telle fonction mais rajouter des fonctions à tout va pour combler des manques de spécifications, je trouve ça risquer et on le vois, cela fait perdre des adhérents au langage ( qui n'est pas du tout un langage dépassé comme le dit l'auteur) . C'est d'ailleurs pour cela que beaucoup d'entreprises (comme le jeux vidéo) n'utilise le C++11 que très rarement et si c'est le cas, on cherchera d'abord une solution de design, plutôt que celle proposé par C++11.
Homer J. Simpson
Certains partent pendant que d'autres nouveaux viennent...
En quoi ça rend le code plus complexe? Car au niveau complexité cyclomatique, le fait d'éliminer des if rend le code moins complexe justement. Ca plus la possibilité de tagger davantage ses variables const (pas possible quand elle doit être modifiée dans un if), ça sécurise le code. En terme de design justement, c'est quand même plus élégant.
Code : Sélectionner tout - Visualiser dans une fenêtre à part const auto host = cmdline::extractArg(argc, argv, "-host").value_or("localhost")
Je ne pense pas que le fond du problème soit C++ mais plutôt le changement des habitudes. C++ (avec d'autres langages) s'oriente vers un style toujours plus fonctionnel et ça frustre quand on est habitué à un style très impératif. Ca s'appelle la résistance au changement. Moi même j'ai été "déçu" ou sceptique au début avec C++11, mais en prenant le temps de comprendre la philosophie sous-jacente j'ai été conquis. Et là rebelote avec C++17 et des feature du genre folding expressions. C'est sûr on n'a pas fini de grincer des dents
Peux-tu détailler ce que tu as en tête ?
Pour moi, naïvement, std::optional permet de simplifier le C++ et renforce le KISS :
- un nom explicite
- une façon "officielle" de renvoyer une valeur qui peut, ou pas, être présente
- à priori, pas d'autre utilisation que celle donnée ci dessus
Bien sur
Je vais reprendre l'exemple d'ici
Output:
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 // optional can be used as the return type of a factory that may fail std::optional<std::string> create(bool b) { if(b) return "Godzilla"; else return {}; } int main() { std::cout << "create(false) returned " << create(false).value_or("empty") << '\n'; // optional-returning factory functions are usable as conditions of while and if if(auto str = create(true)) { std::cout << "create(true) returned " << *str << '\n'; } }
L’équivalent de :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 create(false) returned empty create(true) returned Godzilla
Output:
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 std::string create(bool b, std::string Replacement = std::string()) { if(b) return "Godzilla"; else return Replacement; } int main() { std::cout << "create(false) returned " << create(false, "empty") << '\n'; // optional-returning factory functions are usable as conditions of while and if if(auto str = create(true)) { std::cout << "create(true) returned " << *str << '\n'; } }
Et ceci fonctionne depuis bien longtemps. Une syntaxe qui reste compréhensible même par un étudiant qui apprends les fonctions et leurs paramètres, sans avoir à comprendre une énième classe de std.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 create(false) returned empty create(true) returned Godzilla
Comme je l'ai dit plus haut, je comprends l'utilité d'une telle fonction, mais je trouve que c'est une nouveauté qui par définition grossis les rangs des fonctions std, qui par définition le rends plus complexe à aborder. Et par aborder je ne parle pas de quelqu'un qui à de l'expérience en C++ mais de nouveau venu dans notre univers
Pour l'exemple de Aurelien.Regat-Barrel:
Ce que je vois la c'est que cmdLine est une classe. qui extrait des arguments et retourne une valeur par défaut si pas trouvé, une fois de plus la valeur par défaut peut être situé a plusieurs endroit.
Code : Sélectionner tout - Visualiser dans une fenêtre à part const auto host = cmdline::extractArg(argc, argv, "-host").value_or("localhost")
En paramètre de fonction, dans la fonction elle même. Voir mapper les commandes et les arguments dans un fichier avec une valeur des infos comme la valeur par défaut.
Encore une fois je tiens à préciser que tout n'est pas à jeter dans ce qui est ajouté mais beaucoup de choses ajoutées sont superflus et complexifie le problème en apportant trop de solution.
Homer J. Simpson
C'est un exemple pour illustrer l'utilisation de la classe, pas pour montrer tout ce que ca apporte. Il est evident que optional + value_or fait que ce n'est plus "optionnel" (cela retourne toujours une chaîne) et donc peut être remplacée par ton code. Mais optional n'est pas limite a cet usage.
Un exemple qui est vrai "optionnel", ca serait un url query par exemple :
Il est bien sur possible de faire la même chose avec ton approche, mais en moins concis.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 std::optional<std::string> Params::get(std::string const& p); if (auto param = params.get("host")) url.append("host", param); // ajoute "&host=param a l'url
Toujours le problème classique (pour tous les langages, pas que le C++) entre proposer une fonctionnalité dans le langage/lib standard, ou laisser les devs ecrire le code correspondant. Et c'est une question ou il est impossible de mettre d'accord tout le monde. (On voit régulièrement des gens se plaindre que telle ou telle fonctionnalité est disponible uniquement via une lib et n'est pas dans le standard C++).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 std::string Params::get(std::string const& p, bool * success); bool success { false }; auto param = params.get("host", &success); if (success) url.append("host", param); // ajoute "&host=param a l'url
Mais quand même une remarques : la lib du C++ est très petite, comparée à la majorité des libs "standard" des langages mainstream (Java, C#, Python, etc. Une lib standard minimaliste est plus l'exception que la règle). Penser qu'un étudiant sera plus perdu avec la lib du C++ qu'avec une autre lib me semble un peu exagéré. (Il sera surtout perdu de devoir étudier plusieurs langages et leurs libs respectives, mais ce n'est pas quelques dizaines de nouvelles classes dans la lib du C++ qui va particulièrement lui compliquer son apprentissage).
Surtout que le C++ n'interdit ou force aucune approche, il en propose simplement une nouvelle.
C'est que l'exemple n'est pas très bon.
Plus intéressant, par exemple, une fonction de recherche dans une map qui retournerait une optional< mapped_type &>.
Ou simplement un builder pour une classe ayant un constructeur un peu complexe, ou plusieurs constructeurs. Ce qui peut servir pour parser un fichier d'entrée.
Avant la lecture, rien n'est défini, et tous les types n'ont pas de valeurs "null".
Après la lecture, seule certaines valeurs ont étés lues, selon que l'utilisateur ait voulu utiliser un constructeur ou un autre
Si le builder dispose des parametres utilisés par un des constructeurs, il peut produire un objet.
Personnellement, il me sert surtout pour la représentation de données métiers facultatives. Et du coup, pour les sérializations.
Comment mieux représenter un attribut optionel d'une balise précise d'un flux xml, dans l'objet métier?
Mes principes de bases du codeur qui veut pouvoir dormir:Pour faire des graphes, essayez yEd.
- 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.
le ter nel est le titre porté par un de mes personnages de jeu de rôle
L'intérêt que je vois à ce cas précis, c'est que les autres alternatives sont a peu près toujours du genre:
- T*
- pair<bool, T&>
- variant<Rien, T&>
Avec les inconvénients qui viennent:
le pointeur n'informe pas du tout sur la possession du pointé: Dois-je le libérer. Puis-je utiliser ce pointeur comme argument de telle fonction.
les membres first ou second de la paire n'ont aucune signification sémantique. Sans IDE, je n'arrive jamais à me souvenir lequel est le booléen.
quant à variant, il requiert get<T&>, c'est-à-dire un typage explicite à l'extraction.
optional n'a aucun de ces défauts. Son implémentation est quasiment la même que pair, mais fournit des méthodes utiles: conversion en booléen, accès, accès avec comportement en cas d'absence. Ainsi que des opérateurs de comparaisons (s'ils sont supportés par le type sous-jacent)
Mes principes de bases du codeur qui veut pouvoir dormir:Pour faire des graphes, essayez yEd.
- 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.
le ter nel est le titre porté par un de mes personnages de jeu de rôle
A contraster avec ce que fait Qt depuis... longtemps déjà:
Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part const T QMap::value(const Key & key, const T & defaultValue) const
A propos de C++11 qui est délaissé dans les jeux vidéos et de la complexité de optional, je suis tombé sur cet article aujourd'hui publié sur the longest running platform for game developers:
http://www.gamedev.net/blog/42/entry...ransformation/
CQFDNot bad, but it is taking us 5 lines of code (7 if you include the braces) and if you think about it we should be able to test for the existence of the handler by querying the handler object itself rather than storing, in the calling function, what is going on. Also, the handler gets default constructed on the calling side, which might be a waste too.
So what can C++17 do to help us?
Enter std::optional<T>.
Je ne suis pas fan de cette QMap::value, puisqu'elle retourne systématiquement une copie (de la valeur contenue ou de celle par défaut).
J'aurai préféré qu'elle retourne une référence constante sur ces deux là (puisqu'elle prend la valeur par défaut par référence).
Mes principes de bases du codeur qui veut pouvoir dormir:Pour faire des graphes, essayez yEd.
- 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.
le ter nel est le titre porté par un de mes personnages de jeu de rôle
J'ai déjà vu des boost::optional<Type&>, mais je ne pense pas qu'il soit possible de faire un std::optional<Type&>.
Dans la doc de std::optional<T>, on peut lire que T doit satisfaire les conditions du concept Destructible.
Or, dans le dernier lien, on peut lire : "Thanks to pseudo destructor call, all scalar types meet the requirement of Destructible, while array types and reference types do not. Note that std::is_destructible allows arrays and reference types."
Personnellement, je n'aime pas boost::optional<Type&> à cause de sa lourdeur d'écriture par rapport à Type*.
Pour moi, un pointeur nu devrait presque toujours désigner une adresse optionnelle d'un objet dont on ne gère pas la destruction. Si un programme gère les pointeurs correctement, boost::optional<Type&> est inutile. Cela dit, je reconnais que, quand on maintient un programme qui est déjà très gros avec des pointeurs nus partout, on a souvent d'autres choses plus importantes à faire que de changer des pointeurs nus en références ou en pointeurs intelligents.
(On est HS, mais ce n'est pas trop grave.
Le problème est que Qt est désigné de façon à ce que la très grande majorité des classes sont soit des QObject - donc non-copiable et manipulable que par pointeur -, soit utilisent le COW - et donc la copie n'est pas coûteuse. Ce qui explique en partie pourquoi la move-semantic n'est pas très utilisée dans Qt.
Moralité : il faut probablement éviter les conteneurs Qt pour les classes non Qt.)
Je viens de tester avec Clang sur Coliru.com, cela ne passe effectivement pas. (Avec une erreur incompréhensible, comme d'habitude )
Par contre, ca passe avec std::reference_wrapper. Par contre, c'est un peu lourd.
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 #include <string> #include <iostream> #include <experimental/optional> #include <functional> std::experimental::optional<std::reference_wrapper<int>> get(bool b, int & i, int & j) { if(b) return i; else return j; } int main() { int i { 1 }, j { 2 }; std::cout << i << ' ' << j << std::endl; get(true, i, j).value().get() = -1; std::cout << i << ' ' << j << std::endl; get(false, i, j).value().get() = -2; std::cout << i << ' ' << j << std::endl; }
Bref, difficilement utilisable dans une fonction retourne un element d'une collection.
Il ne faut pas se faire d'illusion, la raison premiere (à mon avis, basee sur aucune source concrete) est la resistance au changement.
la raison première est que tu dois assurer que ton code compile sur quasiememt TOUT les complilateurs. Les publics comme msvc gcc clang et autres et les privées qui sont généralement des publics modifiés pour répondre au besoin d'architecture spécifique. Et dans ce cas, faire un myOptional dans le framework plutôt que d'esperer sa presence sur 100 % des compilateurs est nécessaire.
De plus, la stl essaie de repondre à tout les problème avec une solution, et pas la solution à un problème, ce qui n'est pas sans contreparties meme si la stl est un tres tres bon point de depart pour creer ta solution en supprimant le superflux pour ta solution.
La stl fait tres bien son travail et ce que dis l'auteur sur sa "mort naturel" est faux, MAIS à vouloir trop en faire, la stl grossi à un point que les developpeurs utilise des solutions sans comprendre à 100 % leur entrailles, ce qui fini en fin de projet par faire du code "a peu prêt" car ils ont la boite à outils à tout faire. C++ est un code ou ( je trouve ) on trouve des développeurs aimant rentrer dans les entrailles au plus proche du processeur et de la mémoire.
Apres c'est mon point de vu avec mon expérience. Actuellement, je bosse pour un client avec qui je n'aurais pas cette vision du code vu le projet.. :p
Homer J. Simpson
Tu appelles résistance au changement des outils qui datent parfois de plusieurs années avant leur entrée en STL, parce que nécessaire et utiles, ainsi portés et fonctionnels sur toutes les plateformes ?
"Hé les mecs, ils ont enfin introduit les threads dans la STL, on va supprimer toute notre implémentation pour les utiliser" "hey Bob, gentil ta STL mais std::thread n'est pas dispo sur Wii U.." "Pi en plus leur interface est cheapos, je peux pas renommer un thread ni changer son affinité aux cores sur Xbox One.." "bon laissez tomber, on va garder nos threads en fait"
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.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager