
Envoyé par
Steph_ng8
Je ne comprends pas.
S'il y a une dépendance forte, il ne faut pas en exposer les membres !
J'ai l'impression que tu te contredis

(même si je me doute que c'est plutôt moi qui ne vois pas où tu veux en venir...).
Peut etre as tu déjà entendu parler de std::map 
Il s'agit d'un tableau associatif qui fait le tri sur une donnée qui permet d'en identifier une autre de manière unique.
Les deux choses (la clé et la valeur) représentent fondamentalement la même chose, et, si tu change la clé, c'est que tu manipules, forcément, une autre valeur (l'inverse étant également vrai dans une certaine mesure: si tu modifie certaine données de la valeur, tu devrais sans doute te retrouver avec une autre clé
)
Il y a donc un lien fort entre les deux, parce que l'élément first de la pair représente fondamentalement la même chose que l'élément second!
Si les deux éléments sont publics, c'est essentiellement pour ne pas rajouter une couche de complexité aux algorithmes génériques qui sont utilisés par la std::map 
À moins que tu veux dire
std::pair ne devrait être utilisée qu'en interne ?
A peu de choses près, oui, ou sous la forme d'un itérateur, le plus souvent constant...
Car, si tu modifie l'élément qui sert de clé pour le tri, tu place toute la map dans un état incohérent, du fait qu'un objet va se retrouver à une place qui n'est pas la sienne.
La seule solution pour s'en sortir est alors de veiller à supprimer la paire en question et à en réinsérer une autre
Et qu'entends-tu par « structure "flottante" »

(Rien à voir avec le mot-clé
struct, ça j'ai compris.)
En fait, c'est aussi une struct (la pair est créée avec le mot clé struct
) mais ce sera peut etre plus compréhensible si on observe la tuple.
Peut etre as tu étudié un peu les bases de données, et, dans ce cas, le mot tuple ne t'est pas tout à fait inconnu...
La tuple, en base de données, et un ensemble hétérogène d'éléments "de base" représentant un enregistrement (complexe) dans une table.
Le tout est alors plus important que l'ensemble de ce qui le compose, car une personne est l'ensemble de son nom, de son prénom, de son adresse (qui se subdivise elle-meme en plusieurs informations particulières
) et de son age (par exemple), mais chaque information doit être accessible de manière distincte.
La paire et la tuple fournies par le standard ne font qu'implémenter ce genre de concept!!!
D'ailleurs, c'est bien simple, l'ensemble de la STL ne fait que fournir une implémentation générique de concepts qui sont tout aussi génériques (et qui se doivent donc de respecter des règles génériques
)
C'est là-dessus que j'étais parti pour mes littéraux.
Le problème de la paire, c'est que les deux parties sont intimement liées, mais que les règles sont définies par "quelqu'un d'autre" (par la norme, en fait), et que ces règles:
- risquent fort de ne pas correspondre à tes besoin
- ne peuvent pas être changées
Un bête exemple: l'opérateur < qui sert de base pour le tri est défini de manière à invoquer l'opérateur < exclusivement sur... la première donnée (first), indépendamment de la deuxième, et surtout, indépendamment du type des deux données (ce qui implique d'ailleurs que l'opérateur < doit etre défini pour le type de first :p) .
Si tu veux modifier cette règle, tu devra carrément passer par un foncteur qui agira, le cas échéant, de manière différente sur base du type réel des deux données représentées.
Si, par contre, tu crées ta propre structure (classe) toi même, tu garde toute lattitude pour définir ton propre opérateur < (et tous les autres, si besoin en est) pour faire en sorte, par exemple, que tes littéraux soient d'abord triés sur ceux dont le booléen est à false, puis, pourquoi pas, sur le poids volumique de l'atome (ou sa charge électrique, ou son nom ou... n'importe quelle combinaison envisageable
)
Et tu arrivera à le faire beaucoup plus facilement avec une "structure à toi" qu'avec une paire
Autre exemple.
Je dois utiliser mes littéraux conjointement avec un booléen en tant que clé d'un tableau associatif (héritage privé de
std::map).
Une chance que tu précises que c'est un héritage privé, parce que j'étais sur le point de pousser de hauts cris 
Mais il faut être conscient du fait que l'héritage, qu'il soit public ou privé, est la relation la plus forte qui puisse exister entre deux types (la relation EST-UN pour l'héritage public et la relation "EST IMPLEMENTE EN TERME DE pour l'héritage privé) !!!
Il faut aussi être conscient que, 95 fois sur cent, un héritage privé sera avantageusement remplacé par... une composition classique (par le simple fait de fournir un membre dont le type est celui avec lequel on envisage l'héritage privé)!
Ce n'est pas pour rien que de nombreux langages refusent purement et simplement l'héritage privé 
En interne, j'utilisais encore une
std::pair (eh oui, ça en faisait 3 en tout...).
L'utilisateur n'y a jamais accès, excepté à travers les itérateurs.
(Et encore, il me semble que j'ai limité les itérateurs publics aux itérateurs constants.)
Mais de toute façon, la paire n'est visible que constante, vu que c'est la clé.
Dans ce cas, je peux garder ma paire ?
Il est peut etre temps de te rappeler bien fort un principe de base (sorti tout droit de l'XP, mais bon :p) KISS (Keep It Simple, Stupid)!!!
Si je suis d'accord avec le fait qu'il faut refuser le syndrome du NIH (Not Implemented Here), il faut garder un tout petit peu de sens pratique!!!
Imagines tu le code qu'il te faudra écrire pour, simplement, arriver à obtenir un itérateur si tu n'utilises que les std::pair 
Cela pourrait donner quelque chose comme
std::map<std::pair<std::pair<bool, atom>,std::pair<truc, machin> >::/* const_*/iterator it= begin()
Après l'avoir écrit trois fois, tu regrettera amèrement de ne pas avoir créé une structure ou une classe pour relier ces différentes données!!!
Et je ne te parles même pas du risque d'erreur auquel tu t'expose lors de l'écriture de ce machin (j'ai vraiment du réfléchir à deux fois pour etre sur que je ne créais pas une clé à trois composant et une valeur à un seul... en espérant que tu voulais une clé bi composant et une valeur elle aussi bi composant
)
De toute façon, je ne saurais pas nommer la classe liant ces deux données.
Demande toi simplement à quoi elle sert, et utilise cela comme nom 
Si tu arrives à faire que le nom correspond exactement à ce que tu attends de ta classe, tu as gagné 
Et puis elle n'aurait pas vraiment de sens.
Pouruqoi donc 
Elle représente une responsabilité unique (même si on monte déjà dans la granularité de la responsabilité), elle a donc tout son sens, au contraire 
En plus elle ne serait jamais utilisée ailleurs.
Et alors
où est le problème
ce qui importe, c'est qu'elle fournisse les services que tu en attends et qu'elle te permette d'assurer le respect de l'ORP (One Responsability Principle) !
Personne n'a jamais dit qu'une classe ou qu'une structure n'avait réellement de sens que si elle était utilisée en plusieurs endroits
Partager