namespace std {
inline namespace /*unspecified*/ {
inline constexpr /*unspecified*/ weak_order = /*unspecified*/;
}
}
概要
weak_order
は2つの引数を受け取り、それらを弱順序の上で比較する関数オブジェクトである。
効果
weak_order(a, b)
のように呼び出された時、以下のいずれかと等価(上から順に考慮される)
-
std::weak_order
(本関数オブジェクト)の宣言を含まないコンテキストで、weak_ordering(weak_order(a, b))
が呼び出し可能ならばweak_ordering(weak_order(a, b))
-
decay
を通したa, b
の型T
が浮動小数点型の場合、T
の組み込みの比較演算子およびstrong_order
による順序と一貫するweak_ordering
の値を返す。
さらに、numeric_limits<T>::is_iec559== true
の場合、追加で以下の同値類の順序に従った順序付けを行う。- 全ての
-NaN
-Inf
- 負の正規化数
- 負の非正規化数
±0.0
- 正の非正規化数
- 正の正規化数
+Inf
- 全ての
+NaN
- 全ての
-
weak_ordering(a <=> b)
が呼び出し可能ならばweak_ordering(a <=> b)
-
weak_ordering(strong_order(a, b))
が呼び出し可能ならばweak_ordering(strong_order(a, b))
-
それ以外の場合、呼び出しは不適格。
戻り値
呼び出しが適格ならば、比較結果を表すweak_ordering
の値。
例外
上記「効果」節のそれぞれのケース毎に
- --
- 呼び出される
weak_order(a, b)
およびその戻り値のweak_ordering
への変換が例外を送出するかに従う。 - 投げない。
- 呼び出される
a <=> b
およびその戻り値のweak_ordering
への変換が例外を送出するかに従う。 - 呼び出される
strong_order(a, b)
およびその戻り値のweak_ordering
への変換が例外を送出するかに従う。
定数式に評価される条件
上記「効果」節のそれぞれのケース毎に
- --
- 呼び出される
weak_order(a, b)
およびその戻り値のweak_ordering
への変換が定数評価可能であるかに従う。 - 常に定数評価可能
- 呼び出される
a <=> b
およびその戻り値のweak_ordering
への変換が定数評価可能であるかに従う。 - 呼び出される
strong_order(a, b)
およびその戻り値のweak_ordering
への変換が定数評価可能であるかに従う。
カスタマイゼーションポイント
上記「効果」節2,4,5のケースでは、ユーザー定義のweak_order()
、<=>
演算子を定義、もしくはstrong_order()
へアダプトしておくことによって実行される比較をカスタマイズすることができる。
- --
- 引数
a, b
の型T
と同じ名前空間、もしくはT
の定義内でfriend
関数としてweak_order()
を定義しておく。 - --
- 引数
a, b
の型T
に対して、使用可能な<=>
演算子を定義しておく。 - 引数
a, b
の型T
をstrong_order
にアダプトしておく。
ただし、どのケースにおいてもその戻り値型はweak_ordering
に変換可能でなければならない。
備考
numeric_limits<T>::is_iec559== true
の場合の浮動小数点数の比較において、各同値類間の順序は以下のようになる。
{全ての-NaN
} <
{-Inf
} <
{負の正規化数} <
{負の非正規化数} <
{±0.0
} <
{正の非正規化数} <
{正の正規化数} <
{+Inf
} <
{全ての+NaN
}
それぞれの同値類における順序付けは通常の比較演算子の順序付けに従う。ただし、比較不能である場合はその値は同値として扱われる。すなわち、{±0.0
}および{±NaN
}のそれぞの同値類では全ての値が同値(=
)として扱われる。
例
#include <iostream>
#include <compare>
#include <limits>
struct no_spaceship {
int n1 = 0;
int n2 = 0;
int n3 = 0;
friend auto weak_order(const no_spaceship& lhs, const no_spaceship& rhs) -> std::weak_ordering {
//1 -> 3 -> 2の順で比較
if (auto cmp = lhs.n1 <=> rhs.n1; cmp != 0) return cmp;
if (auto cmp = lhs.n3 <=> rhs.n3; cmp != 0) return cmp;
return lhs.n2 <=> rhs.n2;
}
};
struct have_spaceship {
int n1 = 0;
int n2 = 0;
int n3 = 0;
friend auto operator<=>(const have_spaceship& lhs, const have_spaceship& rhs) -> std::weak_ordering {
//宣言と逆順で比較
if (auto cmp = lhs.n3 <=> rhs.n3; cmp != 0) return cmp;
if (auto cmp = lhs.n2 <=> rhs.n2; cmp != 0) return cmp;
return lhs.n1 <=> rhs.n1;
}
};
int main()
{
std::cout << std::boolalpha;
//2. ユーザー定義weak_order()によるカスタム比較
no_spaceship s1 = {1, 2, 3}, s2 = {2, 1, 3};
std::cout << (std::weak_order(s1, s2) < 0) << std::endl;
std::cout << "\n";
//3. 浮動小数点数の比較
constexpr auto qnan = std::numeric_limits<double>::quiet_NaN();
constexpr auto snan = std::numeric_limits<double>::signaling_NaN();
std::cout << (std::weak_order(-0.0, +0.0) == 0) << std::endl;
std::cout << (std::weak_order(-qnan, +qnan) < 0) << std::endl;
std::cout << (std::weak_order(qnan, snan) == 0) << std::endl;
std::cout << "\n";
//4. ユーザー定義<=>によるカスタム比較
have_spaceship s3 = {1, 2, 3}, s4 = {2, 1, 3};
std::cout << (std::weak_order(s3, s4) < 0) << std::endl;
std::cout << "\n";
//4. 組み込み型の比較
std::cout << (std::weak_order(1, 2) < 0) << std::endl;
}
friend auto operator<=>(const have_spaceship& lhs, const have_spaceship& rhs) -> std::weak_ordering {
#include <iostream>
#include <compare>
#include <limits>
struct no_spaceship {
int n1 = 0;
int n2 = 0;
int n3 = 0;
friend auto weak_order(const no_spaceship& lhs, const no_spaceship& rhs) -> std::weak_ordering {
//1 -> 3 -> 2の順で比較
if (auto cmp = lhs.n1 <=> rhs.n1; cmp != 0) return cmp;
if (auto cmp = lhs.n3 <=> rhs.n3; cmp != 0) return cmp;
return lhs.n2 <=> rhs.n2;
}
};
struct have_spaceship {
出力
true
true
true
true
false
true
バージョン
言語
- C++20
処理系
- Clang: ??
- GCC: 10.1 ✅
- Visual C++: ??