Defined in header <algorithm> | ||
template<class InputIt1,class InputIt2,class Cmp> constexprauto lexicographical_compare_three_way | (1) | (since C++20) |
template<class InputIt1,class InputIt2> constexprauto lexicographical_compare_three_way | (2) | (since C++20) |
Lexicographically compares two ranges[
first1,
last1)
and[
first2,
last2)
using three-way comparison and produces a result of the strongest applicable comparison category type.
If the return type is not one of the three comparison category types, the program is ill-formed:
Contents |
first1, last1 | - | the pair of iterators defining the firstrange of elements to examine |
first2, last2 | - | the pair of iterators defining the secondrange of elements to examine |
comp | - | a function object |
Type requirements | ||
-InputIt1, InputIt2 must meet the requirements ofLegacyInputIterator. |
The value of a comparison category type specified above.
Given\(\scriptsize N_1\)N1 asstd::distance(first1, last1) and\(\scriptsize N_2\)N2 asstd::distance(first2, last2):
template<class I1,class I2,class Cmp>constexprauto 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> usingnamespace 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(unsignedchar x,unsignedchar y){returnstd::toupper(x)<=>std::toupper(y);}; int main(){for(constauto&[s1, s2]:{std::pair{"one"sv,"ONE"sv},{"two"sv,"four"sv},{"three"sv,"two"sv}}){constauto res= std::lexicographical_compare_three_way( s1.cbegin(), s1.cend(), s2.cbegin(), s2.cend(), cmp_icase); show_result(s1, s2, res);}}
Output:
"one" is equal to "ONE""two" is greater than "four""three" is less than "two"
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
LWG 3410 | C++20 | extraneous comparisons between iterators were required | such requirement removed |
returnstrue if one range is lexicographically less than another (function template)[edit] | |
(C++20) | constrained function object implementingx<=> y (class)[edit] |
returnstrue if one range is lexicographically less than another (algorithm function object)[edit] |