Чому оператор! = Видаляється в C ++ 20 для багатьох стандартних типів бібліотек?


44

Згідно 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), навпаки, просто навпаки ...

Відповіді:


62

У 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 :

Якщо для оператора @ вибрано переписаний оператор == кандидат через роздільну здатність перевантаження, його тип повернення повинен бути cv bool, а x @ y інтерпретується як:

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

у кожному випадку, використовуючи вибраний переписаний оператор == кандидат.

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

operator!=Наскільки я можу сказати, всі контейнери були вилучені (перевірте, наприклад, векторний конспект ). Єдині винятки - адаптери контейнерів std::queueі std::stack: я гадаю, що це збереження зворотної сумісності при використанні з сторонніми контейнерами, якщо оператори рівності не симетричні.


7
p1614 може також зацікавити, тому що я вважаю, що саме ця пропозиція усунула перевантаження.
N. Shead

39

Бібліотека нам більше не потрібна 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 - Mothership Land .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.