Как реализовать операторы равенства C ++ (in) для агрегатных структур? - PullRequest
8 голосов
/ 14 февраля 2011

Иногда у меня есть такие структуры -

struct aggregate1 {
  std::string name;
  std::vector<ValueT> options;
  size_t foobar;
  // ...
};

- где (в) равенство просто определяется как (в) равенство всех членов: lhs_name == rhs_name && lhs_options == rhs_options && lhs_foobar == rhs_foobar.

Какой «лучший» способ реализовать это?(Лучше как в: (Runtime-) Эффективность, ремонтопригодность, удобочитаемость)

  • operator== в терминах operator!=
  • operator!= в терминах operator==
  • Отдельные реализации для == и !=
  • Как член или как свободные функции?

Обратите внимание, что этот вопрос касается только (in) ops равенства,сравнение (<, <=, ...) не имеет большого смысла для таких агрегатов.

Ответы [ 4 ]

8 голосов
/ 14 февраля 2011

Я бы сделал это, но, возможно, перенесу определение оператора == в файл cpp. Оставьте оператор! = Быть встроенным

Не забудьте сравнить переменные-члены, которые, скорее всего, будут отличаться первыми, поэтому остальные будут закорочены, а производительность лучше.

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;

  // ...
};
6 голосов
/ 14 февраля 2011

Член или свободная функция - дело вкуса, и написание отдельных реализаций == и != кажется мне скучным, подверженным ошибкам (вы можете забыть члена только в одном из двух операторов, и это будетне торопитесь, чтобы заметить), не добавляя ничего с точки зрения эффективности (вызов другого оператора и применение ! имеет незначительную стоимость).

Решение ограничено тем, "лучше ли внедрять operator== виз operator!= или наоборот?

По моему мнению, с точки зрения удобства обслуживания / читаемости / эффективности это одно и то же, я бы рекомендовал делать это везде одинаково для обеспечения согласованности.Единственный случай, когда вы хотите использовать один или другой в качестве «базового оператора», - это когда вы знаете, что в типах, содержащихся в вашей структуре, этот оператор работает быстрее, чем его отрицание, но я не знаю, когдаэто может произойти.

1 голос
/ 14 февраля 2011

ИМХО, реализуйте как друзья и реализуйте operator== (например, некоторые алгоритмы STL будут полагаться на это), а operator!= должен быть реализован как отрицание оператора равенства.

0 голосов
/ 14 февраля 2011

(-: Самостоятельный ответ: -)

Я хотел бы выделить один аспект агрегатов WRT эффективность :

Порядок оценки op== и op!= не имеет значения для (средней) производительности.

Предполагая отдельные реализации на данный момент и учитывая две крайности (a-eq), все подэлементы равны, и (b-neq) все подэлементы неравны, мы имеем эти случаи:

  • (a-eq) + operator==: необходимо сравнить все подэлементов, чтобы вернуть true
  • (a-eq) + operator!=: необходимо сравнить все подэлементов, чтобы вернуть false
  • (b-neq) + operator==: возвращает false после того, как 1-й подэлемент определен неравно
  • (b-neq) + operator!=: возвращает true после того, как 1-й подэлемент определен неравно

Поскольку производительность в среднем одинакова в любом случае, мне кажется - по крайней мере для меня - более естественной реализация op!= в терминах op==, так как для меня более естественным является реализация операции равенства *. 1033 *

...