Пока я пытался узнать о C ++ операторы, я наткнулся на странный оператор сравнения на cppreference.com,* в таблице, которая выглядела так:
«Ну, если это обычные операторы в C ++, я лучше их изучу», — подумал я. Но все мои попытки выяснить эту тайну не увенчались успехом. Даже здесь, на переполнении стека, мне не повезло в поисках.
И если есть, что именно делает этот оператор?
* Тем временем cppreference.com обновил эту страницу и теперь содержит информацию о<=>
оператор.
Это называется трехстороннее сравнение оператор.
Согласно 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
равны / эквивалентны.
На 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
, <=>
и есть встроенные гетерогенныеoperator<=>(T*, nullptr_t)
, Только сравнения указателей на один и тот же объект / распределение являются константными выражениями.<=>
возвращаетсяpartial_ordering
и может вызываться неоднородно путем расширения аргументов до большего типа с плавающей запятой.<=>
возвращает то же самое, что и базовый тип перечисления<=>
,nullptr_t
,<=>
возвращаетсяstrong_ordering
и всегда даетequal
,T[N] <=> T[N]
возвращает тот же тип, что иT
«s<=>
и выполняет лексикографическое поэлементное сравнение. Здесь нет<=>
для других массивов.void
здесь нет<=>
,Чтобы лучше понять внутреннюю работу этого оператора, прочитайте оригинал бумага.
Этот ответ стал неактуальным, так как ссылка на веб-страницу изменилась
веб-страница, на которую вы ссылаетесь был сломан. В тот день он много редактировался, и разные части не были синхронизированы. Статус, когда я смотрел на это был:
В верхней части страницы перечислены существующие в настоящее время операторы сравнения (в C ++ 14). Здесь нет <=>
там.
В нижней части страницы они должны были перечислить тех же операторов, но они обманывают и добавляют это будущее предложение.
gcc
не знает о <=>
пока (и с -std=c++14
никогда не будет), так
кажется, ты имел в виду a <= > b
, Это объясняет сообщение об ошибке.
Если вы попробуете то же самое через пять лет, вы, вероятно, получите лучшее сообщение об ошибке, что-то вроде <=> not part of C++14.