Почему в C ++ 20 удален оператор! = Для многих типов стандартных библиотек?

Согласно cppreference, std::type_info::operator!= удаляется с C ++ 20, однако, std::type_info::operator== видимо остается.

В чем причина? Я мог бы согласиться с тем, что сравнение на предмет неравенства бессмысленно, но тогда сравнение на равенство также было бы бессмысленным, не так ли?

Аналогичным образом operator!= из многих других типов стандартных библиотек, включая контейнеры, такие как std::unordered_map::operator!= и std::unordered_set::operator!= будут удалены в C ++ 20 согласно cppreference.

Необходимость писать if(!(id1 == id2)) не делает никакой код более ясным по сравнению с if(id1 != id2), напротив, как раз наоборот ...


person Aconcagua    schedule 10.10.2019    source источник


Ответы (2)


В C ++ 20 был изменен способ работы реляционных операторов, особенно с введением оператора космического корабля <=>. В частности, если вы предоставляете только operator==, то a != b переписывается на !(a == b).

Из [over.match.oper] /3.4:

Переписанный набор кандидатов определяется следующим образом:

  • Для реляционных операторов ([expr.rel]) перезаписанные кандидаты включают все непереписанные кандидаты для выражения x ‹=> y.
  • Для операторов реляционного ([expr.rel]) и трехстороннего сравнения ([expr.spaceship]) перезаписанные кандидаты также включают синтезированного кандидата с обратным порядком двух параметров для каждого непереписанного кандидата на выражение y ‹=> x.
  • Для оператора! = ([expr.eq]) перезаписанные кандидаты включают все непереписанные кандидаты для выражения x == y.
  • Для операторов равенства перезаписанные кандидаты также включают синтезированного кандидата с обратным порядком двух параметров для каждого непереписанного кандидата для выражения y == x.
  • Для всех остальных операторов перезаписанный набор кандидатов пуст.

И [over.match.oper] / 9:

Если переписанный кандидат operator == выбран разрешением перегрузки для оператора @, его возвращаемый тип должен быть cv bool, а x @ y интерпретируется как:

  • если @ равно! = и выбранный кандидат является синтезированным кандидатом с обратным порядком параметров,! (y == x),
  • в противном случае, если @ равно! =,! (x == y),
  • в противном случае (когда @ ==), y == x,

в каждом случае с использованием выбранного перезаписанного оператора == кандидата.

Таким образом, явная перегрузка для operator!= больше не требуется. Удаление оператора не изменило семантику сравнения.

Насколько я могу судить, все контейнеры operator!= были удалены (проверьте, например, векторный синопсис ). Единственным исключением являются адаптеры контейнеров std::queue и std::stack: я предполагаю, что они предназначены для сохранения обратной совместимости при использовании со сторонними контейнерами, если операторы равенства не являются симметричными.

person N. Shead    schedule 11.02.2020
comment
p1614 также может представлять интерес, поскольку я считаю, что это было предложение, устраняющее перегрузки. - person N. Shead; 12.02.2020

Нам больше не нужна библиотека, предоставленная operator!=. Предоставление operator== позволяет компилятору поиграть и оценить a != b с точки зрения a == b, и все это само по себе.

[over.match.oper]

3 Для унарного оператора @ с операндом типа, cv -неуказанная версия - T1, а для бинарного оператора @ с левым операндом типа, чья cv-неквалифицированная версия - T1, и правым операндом типа, чья cv-неквалифицированная версия - T2, четыре набора функций-кандидатов, назначенные кандидаты в члены , кандидаты, не являющиеся членами, встроенные кандидаты и переписанные кандидаты, строятся следующим образом:

3.4.3 Для оператора! = ([expr. eq]), перезаписанные кандидаты включают всех непереписанных кандидатов для выражения x == y.

std::type_info и многие другие типы библиотек были удалены operator!= как часть P1614 - Корабль-матка приземлился.

person StoryTeller - Unslander Monica    schedule 10.10.2019