Знаете ли вы историю о мальчике, который не сказал ни слова, пока ему не исполнилось 10 лет? Новый оператор трехстороннего сравнения ‹=›, представленный в стандарте C++20, немного похож на этого маленького мальчика, и если это введение не имеет никакого смысла, то для многих разработчиков C++ не имеет смысла и новый ‹=› оператор. В этой серии из двух статей я распутаю и объясню все, что вам нужно знать о новом операторе ‹=›, также известном как оператор космического корабля, чтобы вы могли легко сравнить его.

Вы знаете историю о мальчике, который не сказал ни слова, пока ему не исполнилось 10 лет? Родители водили его к лучшим специалистам: логопедам, специалистам по развитию ребенка, врачам, психологам — ничего не помогало. Мальчик не сказал ни слова, и никто, даже самые лучшие из специалистов, не мог объяснить, почему. Пока однажды мать мальчика не угостила его горячим шоколадом. «Слишком жарко!» — сказал мальчик. «Мой добрый господин! Ты можешь говорить!» — воскликнула мать, утирая слезы радости, — «почему ты до сих пор ничего не сказал?», — спросила она мальчика. «Пока все было просто отлично», — ответил мальчик…

Как и в истории маленького мальчика, все было в порядке с операторами сравнения C++, которые были унаследованы от C. Операторы и методы сравнения годами оставались нетронутыми, и их роли были ясны, наряду с простым набором правил их использования. .

Пока однажды что-то не ладилось, и возникла потребность в новом методе, поддерживающем трехстороннее сравнение между объектами. Так появился оператор трехстороннего сравнения ‹=›, также известный как оператор космического корабля, как часть нового стандарта C++20.

Но чего не хватало? Нужен ли нам другой способ сравнения объектов? Что такое трехстороннее сравнение? А если годами все было хорошо, то почему вдруг перемены?

Чтобы ответить на все эти вопросы, нам сначала нужно взглянуть на то, как до этого момента все делалось в C++.

Лучше дьявола, которого ты знаешь?

В программировании, когда нам нужно сравнить два элемента, обычно требуется логическое значение (да/нет):

Одно больше/меньше/равно/несравнимо с другим.

Таким образом, поток будет следующим: is A ‹ B, и в зависимости от результата проверка будет A › B. Если ни один из этих вариантов не верен, мы можем сказать, что A == B, но это выходит за рамки нашего запроса, поскольку наш запрос возвращает только «истина» или «ложь». Вывод таков: нам нужно два запроса для проверки трех возможных результатов. Рисунок 2 иллюстрирует процесс сравнения двух операндов, как он работал до C++20.

Совершенно новое трехстороннее сравнение ‹=›, также известное как оператор космического корабля из-за его формы, напоминающей космический корабль, было представлено в новом стандарте C++20. . Этот оператор может возвращать результат трех сравнений, которые были ему перегружены: чем меньше оператор '', тем равно оператору '= =' и оператор больше, чем '›', которые в совокупности образуют следующее: ‹=›.

Если вы уже немного знакомы с C++, вы могли знать, что до того, как был введен оператор космического корабля, программисты иногда использовали функции memcmp() и strcmp(), которые были унаследованы со времен C. Базовая string::compare(), которая была частью современного C++, была (и остается) также опцией сравнения. Эти функции могут предоставить один из трех результатов при сравнении двух строк, и они будут возвращать целое число для указания положительных или отрицательных значений. Хотя эти методы немного запутаны и сложны, вплоть до оператора трехстороннего сравнения, они были буквально единственным способом проведения такого типа сравнений — и вот причина рождения ‹=› оператор.

Оператор космического корабля — это не ракетостроение

Многих разработчиков C++, особенно новичков в C++, оператор трехстороннего сравнения на первый взгляд несколько сбивает с толку. Многие разработчики изо всех сил пытаются понять, откуда «приземлился» этот космический корабль и зачем он вообще был нужен, тем более, что до сих пор, как и в сказке о мальчишках, все казалось просто прекрасно. В этом разделе мы объясняем, что именно делает оператора космического корабля лучше и зачем это нужно. Однако обратите внимание, что объяснения в этом разделе являются частичными и относятся только к тому, что представляет собой трехстороннее сравнение, а также к его основной логике. В этом разделе мы не учим, как на самом деле использовать этот оператор в вашем коде.

В главах 3 и 6 нашей книги Изучение C++, написанной Майклом Хефрати и Рут Хефрати и изданной Manning Publications, мы глубже погружаемся в фактические свойства этой концепции и способы ее использования. в вашем коде конфиденциально.

Так что же такое оператор сравнения? Давайте снова посмотрим на рисунок 2: вы можете видеть, что, используя обычные операторы, мы задаем один вопрос. Например, является ли A‹ чем B? Хотя у нас есть три возможных результата, мы получаем только два возможных результата из трех. Это означает, что нам нужно сделать еще один запрос. Давайте посмотрим, что нам нужно спросить в этом случае:

Вопрос 1. А больше, чем Б?

Затем на основе ответа вы задаете 2-й вопрос:

Вопрос 2: равно ли A значению B?

Новый оператор космического корабля позволяет нам выполнять такое же сжатие с помощью одного запроса. Мы можем использовать его всякий раз, когда значения сравниваются с использованием ‹, ›, ‹=, ›=. Это как пойти на свидание вслепую и спросить: «расскажи мне все, что мне нужно знать о тебе…».

Трехстороннее сравнение позволяет вам получить ответы на вопрос: «Что вы можете сказать мне об отношениях между А и Б».

При трехстороннем сжатии вы задаете только один вопрос и получаете один из трех результатов:

A > B

B > A

A == B

Рисунок 3 иллюстрирует основную логику трехстороннего сравнения. Как видите, в случае A‹B функция трехстороннего сравнения вернет число, меньшее 0. В случае A=B функция трехстороннего сравнения вернет число, равное 0, а в случае A›B функция трехстороннего сравнения вернет число, равное 0. функция вернет число › чем 0.

Огромная ценность этого нового оператора, помимо ультракрутого псевдонима, заключается в том, что с его помощью мы объединяем полный набор трех условий в один дерзкий запрос. Методика трехстороннего сравнения также называется трихотомия — разделение на три категории. Нам не всегда нужно использовать трихотомию в нашем коде, но когда мы это делаем, оператор космического корабля очень удобен и может значительно упростить наш код. Поскольку код сильнее слов, давайте посмотрим на два фрагмента кода ниже.

ОБРАЗЕЦ 1:
A ‹= B && B ‹= A

В этом примере мы спрашиваем: меньше или равно B, а B меньше или равно A?

ОБРАЗЕЦ 2:
!(A ‹ B) && !(B ‹ A)

В этом примере мы спрашиваем: не меньше ли A, чем B, и не меньше ли B, чем A?

Теперь мы можем объединить весь этот беспорядок в небольшой чистый оператор:

A <=> B

Как это круто!

Практическое использование трехстороннего сравнения

Хотя в этой статье мы используем простые примеры, чтобы упростить объяснение сложной концепции, вы, вероятно, догадываетесь, что в реальном коде мы не будем использовать ‹=› для сравнения простых объектов или целых чисел. Логика добавления оператора трехэтапного сравнения в C++20 заключалась в том, чтобы упростить сравнение между сложными типами, такими как строки, списки, последовательности и контейнеры, и мы доберемся до этого во второй части этой статьи.

В следующей статье мы углубимся в оператор космического корабля и узнаем, как использовать его в нашем коде с помощью метода, который может заменить memcmp(), strcmp() и compare().

C++ — это серьезный язык программирования для важного программного обеспечения, который вот уже 30 лет остается одним из лучших языков программирования, и его темпы не снижаются. Куда ни глянь, повсюду отпечатки C++. Никогда не поздно научиться этому, и Моя новая книга, написанная в соавторстве с Майклом Хэфрати и изданная Manning Publications, поможет вам в этом, даже если у вас нет опыта программирования или информатики.