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