Что такое & lt; = & gt; оператор в C ++?

Пока я пытался узнать о C ++ операторы, я наткнулся на странный оператор сравнения на cppreference.com,* в таблице, которая выглядела так:

введите описание изображения здесь

«Ну, если это обычные операторы в C ++, я лучше их изучу», — подумал я. Но все мои попытки выяснить эту тайну не увенчались успехом. Даже здесь, на переполнении стека, мне не повезло в поисках.

Есть ли связь между <=> а также C ++?

И если есть, что именно делает этот оператор?

* Тем временем cppreference.com обновил эту страницу и теперь содержит информацию о<=>оператор.

178

Решение

Это называется трехстороннее сравнение оператор.

Согласно P0515 бумажное предложение:

Есть новый трехсторонний оператор сравнения, <=>, Выражение a <=> b возвращает объект, который сравнивает <0 если a < b, сравнивает >0 если a > bи сравнивает ==0 если a а также b равны / эквивалентны.

Чтобы написать все сравнения для вашего типа, просто напишите operator<=> тот
возвращает соответствующий тип категории:

  • Вернуть _ заказ если ваш тип естественно поддерживает <и мы будем эффективно генерировать <, >, <=, >=, ==, а также !=;
    в противном случае возврат неравенство, и мы будем эффективно генерировать
    == а также !знак равно.

  • Верните сильный, если для вашего типа a == b подразумевает f(a) == f(b) (замещаемость, где f читает только состояние сравнения
    доступны через непристойный интерфейс const), в противном случае возвращаем
    слабый.

cppreference говорит:

Выражения оператора трехстороннего сравнения имеют вид

lhs <=> rhs   (1)

Выражение возвращает объект, который

  • сравнивает <0 если lhs < rhs
  • сравнивает >0 если lhs > rhs
  • и сравнивает ==0 если lhs а также rhs равны / эквивалентны.
161

Другие решения

На 2017-11-11, Комитет ISO C ++ принял Херб Саттерпредложение для <=> Оператор сравнения «Космический корабль» как одна из новых функций, которые были добавлены в C ++ 20. В статье под названием Последовательное сравнение Саттер, Маурер и Браун демонстрируют концепции нового дизайна. Для обзора предложения, вот выдержка из статьи:

Выражение <=> б возвращает объект, который сравнивает <0 если <
б
, сравнивает > 0 если а> б, и сравнивает == 0 если а и б
равный / эквивалент.

Общий случай: Написать все сравнения для вашего типа Икс с типом Y, с членской семантикой, просто напишите:

auto X::operator<=>(const Y&) =default;

Расширенные случаи: Написать все сравнения для вашего типа Икс с типом Y, просто пиши оператор<=> это занимает Y, можешь использовать
= по умолчанию чтобы получить членскую семантику, если это необходимо, и возвращает
соответствующий тип категории:

  • Вернуть _ordering если ваш тип естественно поддерживает <, и мы будем эффективно генерировать симметричные <, >, <знак равно, > =, ==, а также
    !знак равно; в противном случае вернуть _equality, и мы будем эффективно генерировать
    симметричный == а также !знак равно.
  • Вернуть strong_ если для вашего типа а == б подразумевает f (a) == f (b) (замещаемость, где е читает только состояние сравнения, что
    доступен с помощью общественности Const члены), в противном случае возврат
    weak_.

Категории сравнения

Пять категорий сравнения определены как 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здесь нет<=>,

Чтобы лучше понять внутреннюю работу этого оператора, прочитайте оригинал бумага.

93

Этот ответ стал неактуальным, так как ссылка на веб-страницу изменилась

веб-страница, на которую вы ссылаетесь был сломан. В тот день он много редактировался, и разные части не были синхронизированы. Статус, когда я смотрел на это был:

В верхней части страницы перечислены существующие в настоящее время операторы сравнения (в C ++ 14). Здесь нет <=>там.

В нижней части страницы они должны были перечислить тех же операторов, но они обманывают и добавляют это будущее предложение.

gcc не знает о <=>пока (и с -std=c++14никогда не будет), так
кажется, ты имел в виду a <= > b, Это объясняет сообщение об ошибке.

Если вы попробуете то же самое через пять лет, вы, вероятно, получите лучшее сообщение об ошибке, что-то вроде <=> not part of C++14.

11
По вопросам рекламы [email protected]