Увидел недавно оператор <=> в чужом коде и испытал культурный шок. Что за зверь, что он делает и когда использовать? #include #include int main() { int a, b = a = 42 std::cout << (a <=> b == 0) }
Ответ Если вы когда либо писали операторы сравнения в более-менее тяжелых C++ классах, то вы, наверное, замечали, что вся идея построения системы сравнений вокруг классических операторов <, >, == и т.д. и/или вокруг соотношения "less" ("меньше"), на который опираются упорядочивающие алгоритмы стандартной библиотеки неудобна и дико неэффективна. Не существует приемлемого/эффективного способа реализации упорядочивающих соотношений для составных объектов на основе существующих соотношений для их индивидуальных компонентов. Например, для класса class Composite { Type1 a Type2 b Type3 c } лексикографическое сравнение < будет выглядеть примерно так bool operator <(const Composite &lhs, const Composite &rhs) { if (lhs.a != rhs.a) return lhs.a < rhs.a if (lhs.b != rhs.b) return lhs.b < rhs.b return lhs.c < rhs.c } <br>Это, разумеется, катастрофически плохо, ибо такой вариант на некотором шаге выполняет фактически одно и то же сравнение два раза. К примеру, сначала делается lhs.a != rhs.a, а затем lhs.a < rhs.a, то по сути является повторным выполнением одной и той же (возможно тяжелой) операции. Чтобы решить эту проблему, в С++20 предложили новую парадигму реализации сравнений: в качестве основы выступают "трехсторонние" ("3-way") сравнения, хорошо знакомые нам еще из C. Теперь фундаментальным примитивом упорядочивающего сравнения для каждого типа данных будет оператор <=>, выполняющий трехстороннее сравнение. Все остальные виды сравнения будут неявно генерироваться на основе результата оператора <=>. Например, на основе оператора <=> вышеприведенный скетч кода может быть переписан так bool operator <(const Composite &lhs, const Composite &rhs) { if (auto cmp = lhs.a <=> rhs.a cmp != 0) return cmp < 0 if (auto cmp = lhs.b <=> rhs.b cmp != 0) return cmp < 0 if (auto cmp = lhs.c <=> rhs.c cmp != 0) return cmp < 0 return false } (Пример приведен в иллюстративных целях. На самом деле правильнее будет реализовать именно и только оператор <=> для класса Composite и дать компилятору сгенерировать оператор < на его основе.) Так что ответ на ваш вопрос про "когда использовать": никогда и всегда. В коде верхнего уровня он почти никогда не нужен. В вашем примере нет никакого повода использовать <=> вместо обычного ==. А вот в качестве лежащей под всем этим основы для реализации операторов сравнения он нужен почти всегда. Без него вы просто не сможете построить приемлемой реализации лексикографического сравнения для составного объекта. В этой роли большинство из нас уже давно руками выписывали аналог этого оператора в виде какой-то функции. А теперь эта практика будет закреплена на уровне языка. Также в стандартной библиотеке С++20 появится вспомогательная функция std::compare_3way, реализующая трехсторонние сравнения на базе обычных сравнений.