std::compare_weak_order_fallback
| Определено в заголовочном файле <compare>
|
||
inline namespace /* не указано */ { inline constexpr /* не указано */ compare_weak_order_fallback = /* не указано */; } |
(начиная с C++20) | |
| Сигнатура вызова |
||
template< class T, class U > requires /* смотрите ниже */ constexpr std::weak_ordering compare_weak_order_fallback(T&& t, U&& u) noexcept(/* смотрите ниже */); |
(начиная с C++20) | |
Выполняет трёхстороннее сравнение подвыражений t и u и выдаёт результат типа std::weak_ordering, даже если оператор <=> недоступен.
Если std::decay_t<T> и std::decay_t<U> одного типа, std::compare_weak_order_fallback(t, u) является выражением эквивалентности для:
std::weak_order(t, u), если это корректное выражение;- иначе,
t == u ? std::weak_ordering::equivalent :t < u ? std::weak_ordering::less :std::weak_ordering::greater,
- если оба выражения
t == uиt < uкорректны и каждое изdecltype(t == u)иdecltype(t < u)модели boolean-testable, за исключением того, что оцениваютсяtиuтолько один раз.
Во всех остальных случаях std::compare_weak_order_fallback(t, u) имеет неправильный формат, что может привести к сбою подстановки, когда оно появляется в непосредственном контексте инстанцирования шаблона.
Объекты точек настройки
Имя std::compare_weak_order_fallback обозначает объект точки настройки, который является константным функциональным объектом литерального классового типа semiregular. В целях наглядности версия этого типа без cv-квалификации обозначается как __compare_weak_order_fallback_fn.
Все экземпляры __compare_weak_order_fallback_fn равны. Эффекты от вызова разных экземпляров типа __compare_weak_order_fallback_fn для одних и тех же аргументов эквивалентны, независимо от того, является ли выражение, обозначающее экземпляр, lvalue или rvalue, и является ли оно константным или нет (однако volatile-квалифицированный экземпляр не требуется для вызова). Таким образом, std::compare_weak_order_fallback можно свободно копировать, а его копии можно использовать взаимозаменяемо.
Учитывая набор типов Args..., если std::declval<Args>()... соответствует требованиям к аргументам для std::compare_weak_order_fallback выше, __compare_weak_order_fallback_fn модели
std::invocable<__compare_weak_order_fallback_fn, Args...>,std::invocable<const __compare_weak_order_fallback_fn, Args...>,std::invocable<__compare_weak_order_fallback_fn&, Args...>иstd::invocable<const __compare_weak_order_fallback_fn&, Args...>.
Иначе, оператор вызова функции __compare_weak_order_fallback_fn не участвует в разрешении перегрузки.
Пример
#include <compare>
#include <iostream>
// не поддерживает <=>
struct Rational_1
{
int num;
int den; // > 0
};
inline constexpr bool operator<(Rational_1 lhs, Rational_1 rhs)
{
return lhs.num * rhs.den < rhs.num * lhs.den;
}
inline constexpr bool operator==(Rational_1 lhs, Rational_1 rhs)
{
return lhs.num * rhs.den == rhs.num * lhs.den;
}
// поддерживает <=>
struct Rational_2
{
int num;
int den; // > 0
};
inline constexpr std::weak_ordering operator<=>(Rational_2 lhs, Rational_2 rhs)
{
return lhs.num * rhs.den <=> rhs.num * lhs.den;
}
inline constexpr bool operator==(Rational_2 lhs, Rational_2 rhs)
{
return lhs <=> rhs == 0;
}
void print(int id, std::weak_ordering value)
{
std::cout << id << ") ";
if (value == 0)
std::cout << "равно\n";
else if (value < 0)
std::cout << "меньше\n";
else
std::cout << "больше\n";
}
int main()
{
Rational_1 a{1, 2}, b{3, 4};
// print(1, a <=> b); // не работает
print(2, std::compare_weak_order_fallback(a, b)); // работает, по умолчанию < и ==
Rational_2 c{6, 5}, d{8, 7};
print(3, c <=> d); // работает
print(4, std::compare_weak_order_fallback(c, d)); // работает
Rational_2 e{2, 3}, f{4, 6};
print(5, e <=> f); // работает
print(6, std::compare_weak_order_fallback(e, f)); // работает
}
Вывод:
2) меньше
3) больше
4) больше
5) равно
6) равно
Отчёты о дефектах
Следующие изменения поведения были применены с обратной силой к ранее опубликованным стандартам C++:
| Номер | Применён | Поведение в стандарте | Корректное поведение |
|---|---|---|---|
| LWG 2114 | C++20 | резервный механизм требовал только, чтобы возвращаемые типы были преобразованы в bool
|
ограничения усилены |
Смотрите также
(C++20) |
выполняет трёхстороннее сравнение и возвращает результат типа std::weak_ordering (объект точки настройки) |