std::compare_three_way
| Определено в заголовочном файле <compare>
|
||
| Определено в заголовочном файле <functional>
|
||
struct compare_three_way; |
(начиная с C++20) | |
Функциональный объект для выполнения сравнений. Выводит типы параметров и возвращаемый тип оператора вызова функции.
Определяемый реализацией строгий общий порядок указателей
Оператор вызова функции выдаёт определённый реализацией строгий общий порядок указателей, если оператор <=> между аргументами вызывает встроенный оператор сравнения для указателей, даже если встроенный <=> оператор нет.
Строгий общий порядок, определяемый реализацией, согласуется с частичным порядком, налагаемым встроенными операторами сравнения (<=>, <, >, <= и >=), и согласуется со следующими стандартными функциональными объектами:
- std::less, std::greater, std::less_equal и std::greater_equal, когда аргумент шаблона тип указателя или
void
- std::ranges::equal_to, std::ranges::not_equal_to, std::ranges::less, std::ranges::greater, std::ranges::less_equal, std::ranges::greater_equal и std::compare_three_way
Типы элементы
| Тип элемент | Определение |
is_transparent
|
/* не определено */ |
Функции-элементы
operator() |
получает результат трёхстороннего сравнения по обоим аргументам (public функция-элемент) |
std::compare_three_way::operator()
<tbody> </tbody> template< class T, class U > requires std::three_way_comparable_with<T, U> // с разными симантическими требованиями constexpr auto operator()( T&& t, U&& u ) const; |
||
Сравнивает t и u, что эквивалентно return std::forward<T>(t) <=> std::forward<U>(u);, за исключением случаев, когда это выражение разрешается вызовом встроенного operator<=>, сравнивающего указатели.
Когда вызов не вызывает встроенный оператор сравнения указателей, поведение не определено, если std::three_way_comparable_with<T, U> не моделируется.
Когда вызов вызывает встроенный оператор, сравнивающий указатели типа P, вместо этого результат определяется следующим образом:
- Возвращает
std::strong_ordering::less, если (возможно преобразованное) значение первого аргумента предшествует (возможно преобразованному) значению второго аргумента в определяемом реализацией строгом общем упорядочивании по всем значениям указателя типаP. Этот строгий полный порядок согласуется с частичным порядком, заданным встроенными операторами<,>,<=и>=. - Иначе возвращает
std::strong_ordering::greater, если (возможно преобразованное) значение второго аргумента предшествует (возможно преобразованному) значению первого аргумента в том же строгом общем порядке. - Иначе, возвращает
std::strong_ordering::equal.
Поведение не определено, если только последовательности преобразования из T и U в P не сохраняют равенство (смотрите ниже).
Сохранение равенства
Выражения, объявленные в выражениях requires концептов стандартной библиотеки, должны сохранять равенство (если не указано иное).
Пример
#include <compare>
#include <iostream>
struct Rational {
int num;
int den; // > 0
// Хотя сравнение X <=> Y будет работать, прямой вызов
// std::compare_three_way{}(X,Y) требует определения operator==,
// чтобы соответствовать std::three_way_comparable_with.
constexpr bool operator==(Rational const&) const = default;
};
constexpr std::weak_ordering operator<=>(Rational lhs, Rational rhs)
{
return lhs.num * rhs.den <=> rhs.num * lhs.den;
}
void print(std::weak_ordering value)
{
value < 0 ? std::cout << "меньше\n" :
value > 0 ? std::cout << "больше\n" :
std::cout << "равно\n" ;
}
int main()
{
Rational a{6,5};
Rational b{8,7};
print(a <=> b);
print(std::compare_three_way{}(a,b));
}
Вывод:
больше
больше
Отчёты о дефектах
Следующие изменения поведения были применены с обратной силой к ранее опубликованным стандартам C++:
| Номер | Применён | Поведение в стандарте | Корректное поведение |
|---|---|---|---|
| LWG 3530 | C++20 | синтаксические проверки были ослаблены при сравнении указателей |
смягчены только семантические требования |
Смотрите также
(C++20) |
функциональный объект, реализующий x == y (класс) |
(C++20) |
функциональный объект, реализующий x != y (класс) |
(C++20) |
функциональный объект, реализующий x < y (класс) |
(C++20) |
функциональный объект, реализующий x > y (класс) |
(C++20) |
функциональный объект, реализующий x <= y (класс) |
(C++20) |
функциональный объект, реализующий x >= y (класс) |