Что такое оператор <=> в С++?

Пока я пытался узнать о операторах С++, я наткнулся на странный оператор сравнения на cppreference.com, * в таблице, которая выглядит так: введите описание изображения здесь "Ну, если это обычные операторы на С++, я лучше их узнаю", - подумал я. Но все мои попытки разъяснить эту тайну были безуспешными. Даже здесь, в Stack Overflow, мне не повезло в моем поиске.

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

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

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

Ответ 1

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

В соответствии с предложением P0515:

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

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

  • Возвращаем a_ordering, если ваш тип естественно поддерживает < и эффективно генерирует <, >, <=, >=, == и !=; в противном случае верните _equality и хорошо сгенерируйте == и !=.

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

cppreference говорит:

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

lhs <=> rhs   (1)  

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

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

Ответ 2

В 2017-11-11, комитет ISO С++ принял Herb Sutter для оператора трехмерного сравнения &lt= = > " как одного из новых функций, добавленных в С++ 20, В документе под названием Согласованное сравнение Sutter, Maurer и Brown демонстрируют концепции нового дизайна. Для обзора предложения здесь выдержка из статьи:

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

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

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

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

  • Верните _дополнительский, если ваш тип поддерживает < и эффективно генерирует симметричные <, > > , < =, =, == и =!; в противном случае верните _equality и эффективно сгенерируйте симметричный == и !=.
  • Возвращает 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 нет <=>.

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

Ответ 3

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

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

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

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

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

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