12
votes

Comment implémenter les opérateurs d'égalité C ++ (dans) pour les structures agrégates?

Parfois, j'ai des structures telles que ceci - xxx

- où (in) égalité est simplement définie comme (dans) égalité de tous les membres: lhs_name == rhs_name && LHS_OPTIONS == RHS_OPTIONS && LHS_FOOBAR == RHS_FOOBAR .

Quel est le "meilleur" moyen de mettre en œuvre cela? (Meilleur comme dans: (runtime-) efficacité, maintenabilité, lisibilité)

  • opérateur == en termes d'opérateur ! =
  • opérateur! = en termes de opérateur ==
  • Des implémentations séparées pour == et ! =
  • comme membre ou de fonctions libres?

    Notez que cette question ne concerne que les ops d'égalité (IN), comme comparaison ( << / code>, <= , ...) faire trop de sens pour de tels agrégats.


1 commentaires

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é.


4 Réponses :


9
votes

membre ou fonction libre est une question de goût et de rédiger des implémentations séparées de == et ! = 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 ! a un coût négligeable).

La décision est limitée à "est-il préférable d'implémenter opérateur == en termes d'opérateur ! = ou le contraire?

À 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.


0 commentaires

1
votes

IMHO, implémentez en tant qu'amis et implémentez l'opérateur == (certains algorithmes stl s'appuieront sur cela par exemple) et l'opérateur ! = doit être mis en œuvre comme la négation de l'opérateur égal.


0 commentaires

12
votes

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;

  // ...
};


0 commentaires

-1
votes

(-: auto réponse: -)

Je tiens à mettre en évidence un aspect des agrégats WRT Efficacité :

L'ordre d'évaluation de op == et op! = n'est pas pertinent pour la performance (moyenne).

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:

  • (A-EQ) + opérateur == : doit comparer tous les sous-éléments les sous-éléments pour retourner vrai
  • (A-EQ) + Opérateur! = : doit comparer tous les sous-éléments à renvoyer false
  • (b-neq) + opérateur == : retourne false après le 1er sous-élément est déterminé inégal
  • (b-neq) + opérateur! = : retourne true après le 1er sous-élément est déterminé inégal

    É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! = en termes de op == , Comme il se sent plus naturel pour moi de mettre en œuvre l'égalité op.


1 commentaires

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.