perso, laissé la tâche au monsieur(compilo), je le trouve pas idéal car il déplacera l'objet quand il voudra(donc quand il jugera bon de le faire);
par contre, si le développeur le fais seul(en disant au monsieur quoi faire et comment le faire), donc je pourrai déplacer mon objet au bon moment . tu trouve pas ?
Hummm... Ca se discute...
Il faut bien comprendre qu'un compilateur dispose non seulement d'une vue globale de ton unité de compilation bien plus précise que celle que tu crois en avoir (si, si, je t'assure!!!), mais aussi d’heuristiques qui lui permettent très souvent de faire de bien meilleurs choix que toi.
Or, si tu le force à faire quelque chose qu'il n'aurait pas fait ou, au contraire, si tu lui interdit de faire quelque chose qu'il jugeait utile, il respectera tes ordres, et fera ce que tu lui dit de faire même si ton ordre n'a pas de sens de manière la plus générale possible (*).
(*) Il n'y a -- à ma connaissance qu'un seul mot clé que le langage considère d'avantage comme une suggestion que comme un ordre formel: le mot clé inline
EL-jos a écrit:
Nota: et surtout c'est la perf qu'on cherche tous en C++
Je dirais que c'est une raison de plus pour laisser faire le compilateur autant que possible...
Dans la très grosse majorité des cas, les heuristiques du compilateur lui permettront de mettre en place des optimisations dont tu n'as sans doute même pas conscience.
En voulant "tout décider par toi-même", tu risques de lui donner des instructions qui iront à l'encontre de ces heuristiques et qui l'empêcheront donc d'apporter certaines optimisations.
Et le résultat obtenu sera exactement l'inverse de ce que tu voulais: certaines optimisations n'ayant pas été faites, tu auras perdu des performances au lieu d'en gagner.
En plus, le terme de "performances" est dangereux à utiliser seul, car il correspond à plusieurs aspects qui s'opposent généralement
Par exemple : on peut réduire la taille d'un exécutable (ou son emprunte mémoire) en utilisant des boucles, mais les différents tests et les sauts d'adresse mis en place à l'occasion de ces boucles vont réduire la vitesse d'exécution.
A l'inverse, on peut gagner énormément en termes de vitesse en "déroulant" les boucles dans l'exécutable. Mais cela se fera au dépends de sa taille, et donc de son emprunte mémoire.
Alors, tu me parles de performances, oui mais... Desquelles? Où places-tu le curseur entre une emprunte mémoire minimale et une vitesse d'exécution maximale?
Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
Perso je place le curseur sur la rapidité de l’exécutable mais dans cette rapidité j'ai toujours eu une philosophie(c'est de dire au monsieur quoi faire et comment le faire)
- Edité par EL-jos 16 avril 2018 à 14:05:42
Ton présent détermine ton futur et la connaissance te placera au dessus de ta génération .
Perso je place le curseur sur la rapidité de l’exécutable mais dans cette rapidité j'ai toujours eu une philosophie(c'est de dire au monsieur quoi faire et comment le faire)
Et je suis pour ainsi dire persuadé que, avec cette philosophie, tu as sans le vouloir, régulièrement obtenu l'effet inverse
La "bonne" philosophie consiste à travailler par étapes. Les deux premières sont:
S'assurer que les meilleurs choix conceptuels aient été faits
S'assurer que les meilleurs algorithmes aient été utilisés et optimisés autant que faire se peu
Et, seulement après, quand on a la certitude que nous ne pourrons plus rien gagner sur ces deux aspects et SI nous éprouvons des problèmes de performances, passer aux étapes 3 et 4, qui consistent à
Faire un benchmark minutieux pour déterminer les goulots d'étranglements (et choisir, de préférence, les plus importants) et
optimiser (si possible) les points désignés par le benchmark, au besoin, en obligeant le compilateur à faire quelque chose que ses heuristiques ne l'on pas incité à faire
Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
Je n'ai rien inventé du tout!!! C'est ce que l'on m'a dit et répété lorsque je suivais mon bachelor en informatique
Et ce que l'on continue de répéter à longueur de temps à tout débutant qui veut aller "trop vite, trop loin": on commence par faire quelque chose qui fonctionne, puis on fait en sorte que cela fonctionne vite car il ne sert à rien de faire quelque chose qui fonce rapidement dans le mur.
Si tu y tiens, je peux essayer de te trouver des sources que tu trouveras sans doute "plus fiables" que moi... Après tout, je ne suis que l'auteur lambda d'un bouquin sur la qualité du développement, qui a été repris dans la bibliographie de l'agence spatiale européenne comme base pour ses règles de qualité en C, C++ et emeded, hein ?
Mais, en attendant, je peux te justifier ces quatre points:
(1) s'assurer que les meilleurs choix conceptuels (entre autres en termes de structures) aient été fait:
Toute chose étant par ailleurs égale, si tu as le choix entre une structure qui te permet de faire "quelque chose" avec une complexité en O(N²) et une autre qui te permet de faire exactement la même chose avec une complexité en O(log(N) ), le simple fait d'abandonner la première au profit de la deuxième te permettra d'obtenir un temps d'exécution bien plus intéressant.
(2)S'assurer que les meilleurs algorithmes aient été utilisés et optimisés autant que faire se peu:
Pareil: si tu utilises le bon algorithme (en termes de complexité) , tu rapidement constater des différences énormes en termes de performances. J'en ai fait l'expérience dernièrement sur le forum (elle est "diluée" sur plusieurs interventions)
(3)Faire un benchmark minutieux pour déterminer les goulots d'étranglements (et choisir, de préférence, les plus importants):
C'est bien beau de vouloir tout optimiser...
Mais, si c'est pour gagner dix cycles d'horloges sur un processus qui en nécessite un bon milliers pour s'exécuter et qui, de plus, n'est exécuté que toutes les vingt-quatre heures, est-ce que cela vaut vraiment la peine???
N'est-ce pas, quelque part, se donner beaucoup de mal pour rien?
Ne serait-il alors pas plus intéressant, de gagner trois cycles d'horloge sur un processus qui n'en nécessite que 100 pour s'exécuter et qui est exécuté toutes les secondes???
(4)optimiser (si possible) les points désignés par le benchmark, au besoin, en obligeant le compilateur à faire quelque chose que ses heuristiques ne l'on pas incité à faire
rejoint ta philosophie, en évitant de se "faire du mal pour rien". Ce qui peut t'éviter de nombreux cheveux gris et de séances de débuggage effrénées
Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
Deedolith, j'ai jamais compris pourquoi aime-tu le faire à la main? aussi longtemps que la bibliothèque de la STL recommande d'utiliser la méthode
std::exchange...
A mon sens, il n'est pas nécessaire d'écrire ce constructeur a la main. Un pointeur nu est déplaçable, donc le constructeur généré par le compilateur fera exactement le même boulot.
Et si on veut l'ecrire soi même : liste d'initialisation + pas besoin de faire un échange (Il n'y a aucune obligation de mettre "in.mPtr" a nullptr).
A propos de std::exchange, pas besoin ici, un std::swap est suffisant. (Le std::swap fait pareil, mais ne retourne pas l'ancienne valeur).
EL-jos a écrit:
perso, laissé la tâche au monsieur(compilo), je le trouve pas idéal car il déplacera l'objet quand il voudra(donc quand il jugera bon de le faire);
par contre, si le développeur le fais seul(en disant au monsieur quoi faire et comment le faire), donc je pourrai déplacer mon objet au bon moment . tu trouve pas ?
Nota: et surtout c'est la perf qu'on cherche tous en C++
Non, c'est déterministe, c'est pas "quand il veut bien". A pire, si tu ne lui donne pas les bonnes indications (par exemple si tu oublies std::move), il ne peut pas le deviner.
Mais si tu sais comment faire les choses correctement pour les faire a la main, tu sais ce que le compilateur fait aussi et tu n'as pas besoin de faire le boulot a sa place. Et si tu ne sais pas ce que le compilateur fait exactement, comment peux tu prétendre faire mieux que lui ?
Donc dans tous les cas, quand on parle de performances : profiling puis on corrige ce qui doit l'être. Si le compilateur ne fait pas une optimisation, on lui indique de la faire, on ne la fait pas a sa place.
EL-jos a écrit:
Perso je place le curseur sur la rapidité de l’exécutable mais dans cette rapidité j'ai toujours eu une philosophie(c'est de dire au monsieur quoi faire et comment le faire)
Lui indiquer, pas le faire a sa place.
EL-jos a écrit:
oui ce bien tout ça mais dis moi ces 4 philosophies, c'est toi qui les as inventés ou tu les trouve quelque part ?
En fait, koala n'a donné qu'une "philosophie" en 4 etapes, pas 4 philosophies.
Pour completer la reponse de koala sur ce point (qu'il a publié pendant que je redigeais ce message), cela se base sur un constat : avec la complexité et la diversité des architectures d'ordinateurs modernes, il n'est pas possible de prevoir a priori les performances de son code. Il est indispensable de passer par une phase de mesure des performances si on veut optimiser.
De ce constat, on voit qu'un code ne sera pas ecrit en une seule fois, mais pourra être modifié plusieurs fois. Les règles de qualité logicielles (cf wikipedia) seront donc plus importantes que les performances dans un premier temps, en particulier avoir un code évolutif.
koala01 a écrit:
l'auteur lambda d'un bouquin sur la qualité du développement, qui a été repris dans la bibliographie de l'agence spatiale européenne comme base pour ses règles de qualité en C, C++ et emeded, hein ?
l'auteur lambda d'un bouquin sur la qualité du développement, qui a été repris dans la bibliographie de l'agence spatiale européenne comme base pour ses règles de qualité en C, C++ et emeded, hein ?
Bouh,c'est moche, les arguments d'autorité
J'avoue Mais, pour une fois, je n'ai pas pu résister
D'autant plus que ca a beau être un argument d'autorité, il n'en reste pas moins que l'agence spatiale, c'est aussi une autorité en la matière
- Edité par koala01 16 avril 2018 à 16:03:52
Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
Perso je place le curseur sur la rapidité de l’exécutable mais dans cette rapidité j'ai toujours eu une philosophie(c'est de dire au monsieur quoi faire et comment le faire)
Lui indiquer, pas le faire a sa place.
Oui tu as raison gbdivers, je l'avoue .
Ton présent détermine ton futur et la connaissance te placera au dessus de ta génération .
je crois que m'approprié de ton livre sera une bonne idée
mais si jamais je trouvais une erreur de dans je te reprocherai ( mdr)
mais dis moi que fais-tu dans la vie pour avoir un tas des connaissance ?
J'ai un (petit) bachelor en informatique, obtenu en cours du soir. Mais j'ai eu l'occasion, au cours des quinze dernières années de confronter (*) régulièrement mon point de vue avec celui de gens ayant bénéficié d'une formation bien plus poussée que la mienne
Depuis cinq ans, je suis en "congé parental", car étant devenu papa deux fois en à peine un an, j'ai voulu passer un maximum de temps avec mes enfants avant qu'ils ne soient en obligation scolaire.
Mais cela m'a laissé énormément de temps pour faire de la veille technologique, lire de nombreux ouvrages et référence et, bien sur, répondre à de nombreuses questions sur différents forum (dont certaines ont aussi nécessité quelques recherche)
Avant cela, j'ai travaillé pendant deux ans comme développeur pour une société de chemins de fer sur le développement d'un projet de planification à long terme d'utilisation du matériel et du personnel qui était développée en C++, et qui utilisait Qt pour la partie graphique, boost pour de nombreuses fonctionnalités et une base de donnée oracle en arrière plan.
(*)A vrai dire, le terme "confronté" est peut-être mal choisi, car j'essaye généralement d'aborder la discussion sans donner l'impression que "j'ai forcément raison" (et du sous entendu "l'autre a forcément tord"), ce qui m'a permis de prendre de nombreux arguments valable en compte et de faire évoluer mon point de vue (**).
(**) je parle volontiers de faire évoluer mon point de vue, car, à moins que l'on ne me démontre par A + B que je me plante complètement, le résultat tient d'avantage d'un "compromis" entre les deux points de vue que de l'acceptation pure et simple à la "bah, si tu le dis, tu as forcément raison".
(***) Et le plus marrant de tout, c'est que je constate au fil du temps que les gens avec qui je discute et auxquels j'ai proposé ces compromis finissent souvent par "faire leur" ces idées que j'ai eu du mal à faire accepter à la base... Mais là, je me laisse aller à l'auto satisfaction
Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
Deedolith, j'ai jamais compris pourquoi aime-tu le faire à la main? aussi longtemps que la bibliothèque de la STL recommande d'utiliser la méthode
std::exchange....
Nota: éclaircie moi un peu là dessus.
Exactement comme l'a noté le koala de memoire, le dernier bon bouquin que j'ai lu (indice: lipmann) ne mentionne pas std::exchange.
Dans le cas des pointeurs nu, ces derniers doivent être déplacés d'une façon ou d'une autre, ce qui implique d'implémenter un constructeur adequat (et operateur=() )
au final, ca pourrais ressembler à quelque chose comme ceci:
A mon sens, il n'est pas nécessaire d'écrire ce constructeur a la main. Un pointeur nu est déplaçable, donc le constructeur généré par le compilateur fera exactement le même boulot.
Hmm, il me semblait que dans le cas des types primitifs (ce qui après tout, est le cas des pointeurs nu), la fonction move se "contentais" de faire une copie ? Et s'ils sont déplaçable, je ne voit plus bcp de raison pour le constructeur / opérateur de mouvements d'exister ...
Oui, le move = une copie dans ce cas. Et c'est ce que tu fais aussi au final, donc pas de différence entre ton constructeur manuel et le constructeur généré automatiquement par le compilateur.
Deedolith a écrit:
Et s'ils sont déplaçable, je ne voit plus bcp de raison pour le constructeur / opérateur de mouvements d'exister ...
Tu veux dire "dans le cas general" ou juste dans le cas particulier des types primitifs ?
Oui, le move = une copie dans ce cas. Et c'est ce que tu fais aussi au final, donc pas de différence entre ton constructeur manuel et le constructeur généré automatiquement par le compilateur.
Heu, je fais une copie et j'invalide le pointeur source ... histoire d'assurer que lorsque le pointeur source sera détruit, cela n'aura pas d'influance sur le pointeur cible.
gbdivers a écrit:
Tu veux dire "dans le cas general" ou juste dans le cas particulier des types primitifs ?
Je viens de voir que tu avais changé ton code après mon message, pour ajouter std:exchange. Dans ce cas, effectivement, il faut invalider le pointeur si la classe conserve l'ownership, pour éviter d'avoir un partage et un double delete. Je n'avais pas compris ce que tu voulais dire.
Je n'avais pas bien lu et donc compris le code, autant pour moi je suis désolé, je viens de saisir.
La question maintenant, c'est, ben à quoi ca va me servir, vu que ma classe ne comporte pas (encore) d'attributs, je ne peux donc pas laisser ce constructeur vide.
Pour la simplicité, voici le prototype de ma classe
#pragma once
#include <memory>
#include "reseau.h"
class Profile
{
Profile(ProfileInfos&& profileInfos);
public:
Profile(Profile&&);
static std::unique_ptr<Profile> createProfile(ProfileInfos&& profileInfos);
};
Je n'ai rien a move pourtant j'ai toujours cette erreur m'indiquant que Profile::Profile n'est pas accessible.
Encore une fois excusez moi si je dis une bêtise, je suis un peu perdu.
"La valeur n'attend point le nombre des années" Le Cid, Pierre Corneille, Don Rodrigue parlant au Comte
Je n'ai mis que la partie concernée, si vous voulez le code du constructeur de la classe je peux vous le donner.
L'erreur se situe dans le fichier memory, ici
template<class _Ty,
class... _Types,
enable_if_t<!is_array_v<_Ty>, int> = 0>
_NODISCARD inline unique_ptr<_Ty> make_unique(_Types&&... _Args)
{ // make a unique_ptr
return (unique_ptr<_Ty>(new _Ty(_STD forward<_Types>(_Args)...)));//ERREUR('Profile::Profile' : impossible d'accéder à private membre déclaré(e) dans la classe 'Profile')
}
"La valeur n'attend point le nombre des années" Le Cid, Pierre Corneille, Don Rodrigue parlant au Comte
perso, je crois qu'il y a problème de compatibilité au niveau de ta fonction std::unique_ptr<Profile> Profile::createProfile(ProfileInfos&& profileInfos)
dans le corps de cette dernière tu fait un returnstd::make_unique<Profile>(std::move(profileInfos));
aussi longtemps que tu indique que la fonction doit retourner un " unique_ptr<Profile> "; donc essaie de faire ceci:
Oui je sais bien, d'où le titre de mon topic, car je voulais pas que le constructeur soit public donc je pensais mettre make_unique en amie, mais ce n'est pas une bonne idée.
Je cherchais donc une autre solution.
"La valeur n'attend point le nombre des années" Le Cid, Pierre Corneille, Don Rodrigue parlant au Comte
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Ton présent détermine ton futur et la connaissance te placera au dessus de ta génération .
Ton présent détermine ton futur et la connaissance te placera au dessus de ta génération .
Discord NaN. Mon site.
Ton présent détermine ton futur et la connaissance te placera au dessus de ta génération .
Ton présent détermine ton futur et la connaissance te placera au dessus de ta génération .
Ton présent détermine ton futur et la connaissance te placera au dessus de ta génération .
Ton présent détermine ton futur et la connaissance te placera au dessus de ta génération .
Discord NaN. Mon site.
Discord NaN. Mon site.
Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C
Ton présent détermine ton futur et la connaissance te placera au dessus de ta génération .
std::make_unique appelle le constructeur de ta classe, ce dernier doit donc être publique.