Parfois, j'ai des structures telles que ceci - - où (in) égalité est simplement définie comme (dans) égalité de tous les membres: Quel est le "meilleur" moyen de mettre en œuvre cela? (Meilleur comme dans: (runtime-) efficacité, maintenabilité, lisibilité) p> Notez que cette question ne concerne que les ops d'égalité (IN), comme comparaison ( lhs_name == rhs_name && LHS_OPTIONS == RHS_OPTIONS && LHS_FOOBAR == RHS_FOOBAR CODE>. P>
opérateur == code> en termes d'opérateur
! = code> li>
opérateur! = code> en termes de
opérateur == code> li>
== code> et
! = code> li>
<< / code>,
<= code>, ...) faire trop de sens pour de tels agrégats. p> p>
4 Réponses :
membre ou fonction libre est une question de goût et de rédiger des implémentations séparées de La décision est limitée à "est-il préférable d'implémenter À mon avis, en termes de maintenabilité / lisibilité / efficacité, c'est la même chose; Je recommanderais seulement de le faire de la même manière partout partout pour la cohérence. Le seul cas où vous voudrez préférer utiliser l'un ou l'autre comme "opérateur de base" est lorsque vous savez que, dans les types contenus dans votre structure, cet opérateur est plus rapide que sa négation, mais je ne sais pas quand cela pourrait arriver. p> == code> et
! = code> me semble ennuyeux, Erreur-ornée (vous pouvez oublier un Membre dans un seul des deux opérateurs, et il faudra du temps pour noter) sans rien ajouter en termes d'efficacité (appeler l'autre opérateur et appliquer
! code> a un coût négligeable). P>
opérateur == code> en termes d'opérateur
! = code> ou le contraire? P>
IMHO, implémentez en tant qu'amis et implémentez l'opérateur == code> (certains algorithmes stl s'appuieront sur cela par exemple) et l'opérateur
! = code> doit être mis en œuvre comme la négation de l'opérateur égal. p>
Je ferais cela, mais peut-être déplacer l'opérateur == Définition du fichier CPP. Laissez l'opérateur! = Pour être en ligne
N'oubliez pas de comparer les variables des membres qui sont les plus susceptibles de différer d'abord afin que le reste est court-circuité et la performance est meilleure. P>
struct aggregate1 { bool operator==(const aggregate1& rhs) const { return (name == rhs.name) && (options == rhs.options) && (foobar == rhs.foobar); } bool operator!=(const aggregate1& rhs) const { return !operator==(rhs); } std::string name; std::vector<ValueT> options; size_t foobar; // ... };
(-: auto réponse: -) p>
Je tiens à mettre en évidence un aspect des agrégats WRT Efficacité EM>: P>
L'ordre d'évaluation de Assumer des implémentations distinctes pour le moment et compte tenu des deux sous-éléments égaux et (B-NEQ) Tous les sous-éléments inégals, nous avons ces cas: P>
Étant donné que la performance en moyenne est la même de la même manière qu'il semble - au moins pour moi - plus naturel d'implémenter op == code> et
op! = code> n'est pas pertinent pour la performance (moyenne). P>
opérateur == code>: doit comparer tous les sous-éléments em> les sous-éléments pour retourner vrai li>
Opérateur! = CODE>: doit comparer tous les sous-éléments em> à renvoyer false li>
opérateur == code>: retourne false après le 1er sous-élément est déterminé inégal li>
opérateur! = code>: retourne true après le 1er sous-élément est déterminé inégal li>
ul>
op! = code> en termes de
op == code>, Comme il se sent plus naturel pour moi de mettre en œuvre l'égalité op. p>
Je ne comprends pas comment vous arrivez à votre conclusion. Opérateur == et opérateur! = prendra toujours le même temps pour calculer et cela ne compte pas autour de vous les mettre en œuvre. N'oubliez pas de garder celui que vous écrivez en termes de lignes pour que vous ne payiez aucune pénalité d'appel.
Avantage d'utiliser une fonction libre est qu'il permet une conversion du premier argument comme BOOL B = 2 == FOO {2}; L'exploitation d'égalité et d'inégalité peut être définie de l'autre, mais j'en tiens à la convention pour définir l'opérateur d'égalité.