std::lexicographical_compare_three_way
From cppreference.com
| ヘッダー <algorithm> で定義 |
||
| template< class InputIt1, class InputIt2, class Cmp > constexpr auto lexicographical_compare_three_way |
(1) | (C++20以降) |
| template< class InputIt1, class InputIt2 > constexpr auto lexicographical_compare_three_way |
(2) | (C++20以降) |
辞書順で2つの範囲 [first1, last1) と [first2, last2) を3方向比較で比較し、適用可能な中で最も強い比較カテゴリ型の結果を生成します。
1) 両方の範囲で、comp に基づいて最初に等しくない要素のペア間の順序を返します。もしそのようなペアがない場合(一方の範囲が、comp に基づいてもう一方の範囲のプレフィックスと等しい場合)、両方の範囲の長さの間の順序を返します。
2) return std::lexicographical_compare_three_way(
first1, last1, first2, last2, std::compare_three_way()); と同等です。
first1, last1, first2, last2, std::compare_three_way()); と同等です。
戻り値の型が3つの比較カテゴリ型のいずれでもない場合、プログラムは不正形式です。
目次 |
[編集] パラメータ
| first1, last1 | - | 調べる最初の要素の範囲を定義するイテレータのペア |
| first2, last2 | - | 調べる2番目の要素の範囲を定義するイテレータのペア |
| comp | - | 関数オブジェクト |
| 型要件 | ||
-InputIt1, InputIt2 は LegacyInputIterator の要件を満たす必要がある。 | ||
[編集] 戻り値
上記の比較カテゴリ型の値。
[編集] 複雑性
N1をstd::distance(first1, last1)、N2をstd::distance(first2, last2)とすると、
1) compの適用は最大でmin(1,N2)回。
[編集] 実装例
template<class I1, class I2, class Cmp> constexpr auto lexicographical_compare_three_way(I1 f1, I1 l1, I2 f2, I2 l2, Cmp comp) -> decltype(comp(*f1, *f2)) { using ret_t = decltype(comp(*f1, *f2)); static_assert(std::disjunction_v< std::is_same<ret_t, std::strong_ordering>, std::is_same<ret_t, std::weak_ordering>, std::is_same<ret_t, std::partial_ordering>>, "The return type must be a comparison category type."); bool exhaust1 = (f1 == l1); bool exhaust2 = (f2 == l2); for (; !exhaust1 && !exhaust2; exhaust1 = (++f1 == l1), exhaust2 = (++f2 == l2)) if (auto c = comp(*f1, *f2); c != 0) return c; return !exhaust1 ? std::strong_ordering::greater: !exhaust2 ? std::strong_ordering::less: std::strong_ordering::equal; } |
[編集] 例
このコードを実行
#include <algorithm> #include <cctype> #include <compare> #include <iomanip> #include <iostream> #include <string_view> #include <utility> using namespace std::literals; void show_result(std::string_view s1, std::string_view s2, std::strong_ordering o) { std::cout << std::quoted(s1) << " is "; std::is_lt(o) ? std::cout << "less than ": std::is_gt(o) ? std::cout << "greater than ": std::cout << "equal to "; std::cout << std::quoted(s2) << '\n'; } std::strong_ordering cmp_icase(unsigned char x, unsigned char y) { return std::toupper(x) <=> std::toupper(y); }; int main() { for (const auto& [s1, s2] : { std::pair{"one"sv, "ONE"sv}, {"two"sv, "four"sv}, {"three"sv, "two"sv} }) { const auto res = std::lexicographical_compare_three_way( s1.cbegin(), s1.cend(), s2.cbegin(), s2.cend(), cmp_icase); show_result(s1, s2, res); } }
出力
"one" is equal to "ONE" "two" is greater than "four" "three" is less than "two"
[編集] 不具合報告
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| LWG 3410 | C++20 | イテレータ間の不要な比較が必要でした。 | その要件は削除されました。 |
[編集] 関連項目
| ある範囲が別の範囲より辞書順で小さい場合に true を返す (関数テンプレート) | |
| (C++20) |
x <=> y を実装する制約付き関数オブジェクト (クラス) |
| ある範囲が別の範囲より辞書順で小さい場合に true を返す (アルゴリズム関数オブジェクト) |