Dlaczego operator! = Usunięto w C ++ 20 dla wielu standardowych typów bibliotek?

44

Zgodnie z cppreference , std::type_info::operator!=zostaje usunięty z C ++ 20, jednak std::type_info::operator==najwyraźniej pozostaje.

Jakie jest uzasadnienie? Mógłbym się zgodzić na to, że porównywanie nierówności byłoby pozbawione sensu, ale wtedy porównywanie dla równości byłoby równie samo pozbawione znaczenia, prawda?

Podobnie, operator!=wiele innych standardowych typów bibliotek, w tym kontenery takie jak std::unordered_map::operator!=i std::unordered_set::operator!=zostaną usunięte w C ++ 20 zgodnie z cppreference.

Konieczność pisania if(!(id1 == id2))nie czyni żadnego kodu jaśniejszym w porównaniu do if(id1 != id2), wręcz przeciwnie ...

Aconcagua
źródło

Odpowiedzi:

62

W C ++ 20 sposób działania operatorów relacyjnych został zmieniony, zwłaszcza wraz z wprowadzeniem <=>operatora statku kosmicznego . W szczególności Jeśli podasz tylko operator==, a != bzostanie przepisane na !(a == b).

Od [over.match.oper] /3.4 :

Przepisany zestaw kandydatów jest określany w następujący sposób:

  • W przypadku operatorów relacyjnych ([expr.rel]) ponownie przepisani kandydaci obejmują wszystkich nieodpisanych kandydatów na wyrażenie x <=> y.
  • W przypadku operatorów relacyjnych ([wyraż. Rel.]) I trójstronnego porównania ([wyraż. Kosm.]) Przepisani kandydaci zawierają również kandydata zsyntetyzowanego, z odwróconą kolejnością dwóch parametrów, dla każdego nie przepisanego kandydata dla wyrażenie y <=> x.
  • W przypadku operatora! = ([Wyraż. Eq]) przepisani kandydaci obejmują wszystkich kandydatów, którzy nie przepisali wyrażenia x == y.
  • W przypadku operatorów równości, przepisani kandydaci zawierają również kandydata zsyntetyzowanego, z odwróconą kolejnością dwóch parametrów, dla każdego nie przepisanego kandydata dla wyrażenia y == x.
  • W przypadku wszystkich innych operatorów przepisany zestaw kandydatów jest pusty.

I [over.match.oper] / 9 :

Jeśli przepisany operator == zostanie wybrany przez rozdzielczość przeciążenia dla operatora @, jego typem zwrotnym jest cv bool, a x @ y jest interpretowane jako:

  • jeśli @ jest! = a wybrany kandydat jest zsyntetyzowanym kandydatem o odwróconej kolejności parametrów,! (y == x),
  • w przeciwnym razie, jeśli @ to! =,! (x == y) ,
  • w przeciwnym razie (gdy @ to ==), y == x,

w każdym przypadku przy użyciu wybranego przepisanego operatora == kandydat.

W związku z tym wyraźne przeciążenie operator!=nie jest już konieczne. Usunięcie operatora nie zmieniło semantyki porównania.

operator!=O ile mi wiadomo, wszystkie pojemniki zostały usunięte (sprawdź np . Streszczenie wektora ). Jedynymi wyjątkami są adaptery kontenerów std::queuei std::stack: zgaduję, że ma zachować wsteczną kompatybilność, gdy jest używana z kontenerami innych firm, na wypadek, gdyby operatory równości nie były symetryczne.

N. Shead
źródło
7
p1614 może być również interesujący, ponieważ uważam, że była to propozycja, która usunęła przeciążenia.
N. Shead
39

Nie potrzebujemy operator!=już dostarczonej biblioteki . Udostępnianie operator==pozwala kompilatorowi na samodzielne przeprowadzanie żonglowania i ocenianie a != bpod względem a == b.

[over.match.oper]

3 Dla operatora jednoargumentowego @ z operandem typu, którego wersja bez cv to T1, i dla operatora binarnego @ z lewym operandem typu, którego wersja bez cv to T1 i prawy operand typu, którego cv- wersja niekwalifikowana to T2, cztery zestawy funkcji kandydujących, wyznaczeni kandydaci na członków, kandydaci niebędący członkami, kandydaci wbudowani i kandydaci przepisani są zbudowani w następujący sposób:

3.4.3 W przypadku operatora! = ([Wyraż. Eq]) przepisani kandydaci obejmują wszystkich kandydatów, którzy nie przepisali wyrażenia x == y.

std::type_infoi wiele innych typów bibliotek zostało operator!=usuniętych w ramach P1614 - The Mothership wylądował .

StoryTeller - Unslander Monica
źródło