На 2017-11-11 , Комітет з ISO C ++ прийнятий Herb Sutter пропозиції «s для <=> оператора порівняння триходового" космічного корабля " в якості одного з нових функцій , які були додані в C ++ 20 . У статті під назвою Послідовне порівняння Саттер, Маурер та Браун демонструють концепції нового дизайну. Огляд пропозиції, ось уривок із статті:
Вираз a <=> b повертає об'єкт, який порівнює <0, якщо a <b , порівнює > 0, якщо a> b , і порівнює == 0, якщо a і b рівні / еквівалентні.
Поширений випадок: щоб написати всі порівняння для вашого типу X із типом Y із семантиками, що належать до членів, просто напишіть:
auto X::operator<=>(const Y&) =default;
Розширені випадки. Щоб написати всі порівняння для типу X із типом Y , просто напишіть оператор <=>, який приймає Y , за допомогою цього пункту можна використовувати
= за замовчуванням, щоб отримати семантику членства, і поверне відповідний тип категорії:
- Повертає _ordering , якщо ваш тип природним чином підтримує < , і ми будемо ефективно генерувати симетричний < , > , <= , > = , == і
! = ; інакше повернемо _рівність , і ми будемо ефективно генерувати симетричні == і ! = .
- Повертайтеся strong_, якщо для вашого типу a == b означає f (a) == f (b) (замінюваність, де f читає лише стан порівняння, який доступний за допомогою публічних членів const ), інакше поверніть
слабкий_ .
Порівняльні категорії
П'ять категорій порівняння визначаються як std::типи, кожна з яких має такі заздалегідь задані значення:
+--------------------------------------------------------------------+
| | Numeric values | Non-numeric |
| Category +-----------------------------------+ |
| | -1 | 0 | +1 | values |
+------------------+------+------------+---------------+-------------+
| strong_ordering | less | equal | greater | |
| weak_ordering | less | equivalent | greater | |
| partial_ordering | less | equivalent | greater | unordered |
| strong_equality | | equal | nonequal | |
| weak_equality | | equivalent | nonequivalent | |
+------------------+------+------------+---------------+-------------+
Неявні перетворення між цими типами визначаються наступним чином:
strong_orderingзі значеннями { less, equal, greater} неявно перетворює в:
weak_orderingзі значеннями { less, equivalent, greater}
partial_orderingзі значеннями { less, equivalent, greater}
strong_equalityзі значеннями { unequal, equal, unequal}
weak_equalityзі значеннями { nonequivalent, equivalent, nonequivalent}
weak_orderingзі значеннями { less, equivalent, greater} неявно перетворює в:
partial_orderingзі значеннями { less, equivalent, greater}
weak_equalityзі значеннями { nonequivalent, equivalent, nonequivalent}
partial_orderingзі значеннями { less, equivalent, greater, unordered} неявно перетворює в:
weak_equalityзі значеннями { nonequivalent, equivalent, nonequivalent, nonequivalent}
strong_equalityзі значеннями { equal, unequal} неявно перетворюється на:
weak_equalityзі значеннями { equivalent, nonequivalent}
Тристороннє порівняння
<=>Маркер вводиться. Послідовність символів в старому вихідному коді <=>вказується на <= >. Наприклад, X<&Y::operator<=>потрібно додати пробіл, щоб зберегти своє значення.
Оператор, що завантажується, <=>- це тристороння функція порівняння та має перевагу вище <та нижче <<. Він повертає тип, який можна порівняти з буквальним, 0але допускаються інші типи повернення, такі як підтримка шаблонів виразів. Усі <=>оператори, визначені мовою та стандартною бібліотекою, повертають один із 5 вищезгаданих std::типів категорії порівняння.
Для мовних типів <=>надаються такі вбудовані порівняння одного типу. Усі є constexpr , за винятком випадків, коли зазначено інше. Ці порівняння не можна викликати неоднорідно, використовуючи скалярні рекламні акції / конверсії.
- Для
bool, інтегральних та вказівних типів, <=>повертається strong_ordering.
- Для типів вказівників різним cv-кваліфікаціям та перетворенням на базу дозволяється викликати однорідну вбудовану
<=>, а є вбудовані гетерогенні operator<=>(T*, nullptr_t). Лише порівняння покажчиків на один і той же об'єкт / розподіл є постійними виразами.
- Для основних типів з плаваючою точкою
<=>повертаються partial_orderingі можуть бути викликані неоднорідно шляхом розширення аргументів до більшого типу з плаваючою точкою.
- Для перерахувань
<=>повертає те саме, що і базовий тип перерахування <=>.
- Для
nullptr_t, <=>повернень strong_orderingі завжди дає equal.
- Для масивів, що копіюються,
T[N] <=> T[N]повертає той самий тип, Tщо <=>і s, і виконує лексикографічне порівнювання елементів. Для <=>інших масивів немає.
- Бо
voidнемає <=>.
Щоб краще зрозуміти внутрішню роботу цього оператора, будь ласка, прочитайте оригінальний документ . Це саме те, що я дізнався за допомогою пошукових систем.