В C ++ нужно перегрузить оператор == в обоих направлениях? - PullRequest
0 голосов
/ 14 ноября 2018

Допустим, я работаю с классом:

class Foo{
public:
  std:string name;
  /*...*/
}/*end Foo*/

, и я предоставляю перегрузку для operator==

bool operator==(const Foo& fooObj, const std::string& strObj) {
    return (fooObj.name == strObj);
}

Нужно ли мне повторно реализовать ту же логику вобратный?

bool operator==(const std::string& strObj, const Foo& fooObj) {
    return (strObj == fooObj.name);
}

Ответы [ 2 ]

0 голосов
/ 14 ноября 2018

Да, вы делаете.Как и во многих других языках, C ++ принимает стороны, и сравнение между двумя объектами разных типов приведет к вызовам двух разных операторов сравнения в зависимости от порядка.

Конечно, вы хотите, чтобы они были согласованными, а неУдивительно, поэтому второе должно быть определено в терминах первого.

0 голосов
/ 14 ноября 2018

(C ++ 20 и более)

С принятием p1185 в C ++ 20 вам не нужнообеспечить более одной перегрузки.В документ внесены эти изменения (среди прочих) в стандарт:

[over.match.oper]

3,4 - [...] Для оператора != ([expr.eq]) переписанные кандидаты включают всех членов, не являющихся членами и встроенных кандидатов для оператора ==, для которого переписанное выражение (x == y) хорошо- формируется при контекстном преобразовании в bool с использованием этого оператора ==.Для операторов равенства переписанные кандидаты также включают в себя синтезированный кандидат с обратным порядком двух параметров для каждого члена, не являющегося членом, и встроенного кандидата для оператора ==, для которого переписанное выражение (y == x)является правильно сформированным при контекстном преобразовании в bool с использованием этого оператора ==.[Примечание: кандидат, синтезированный из кандидата в члены, имеет свой неявный параметр объекта в качестве второго параметра, поэтому неявные преобразования рассматриваются для первого, но не для второго параметра.- конец примечания] [...]

8 [...] Если переписанный кандидат выбран по разрешению перегрузки для оператора !=, x != y интерпретируется как (y == x) ? false : true, если выбранный кандидат является синтезированным кандидатом с обратным порядком параметров, или (x == y) ? false : true в противном случае с использованием выбранного переписанного operator== кандидата.Если переписанный кандидат выбран с помощью разрешения перегрузки для оператора ==, x == y интерпретируется как (y == x) ? true : false с использованием выбранного переписанного operator== кандидата.

Вышеуказанное означает, что не толькоВы не должны предоставить оператору порядок операндов в обратном порядке, вы также получите != бесплатно!Кроме того, функция operator== может быть членом, если это имеет смысл.Хотя, как отмечается в первом абзаце, говорится, что членство или свободная функция будут влиять на неявные преобразования, поэтому вам все равно нужно помнить об этом.


(до C ++ 17)

Вы делаете, если хотите поддерживать сравнения, где строка слева, иFoo справа.Реализация не будет переупорядочивать аргументы в перегруженном operator==, чтобы заставить его работать.

Но вы можете избежать повторения логики реализации.Предполагая, что ваш оператор должен вести себя как ожидалось:

inline bool operator==(const std::string& objA, const Foo& objB) {
    return objB == objA; // Reuse previously defined operator
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...