Namespaces
Variants
Views
Actions

Difference between revisions of "Template:cpp/container/operator cmp"

From cppreference.com
m (Synopsis: +(since C++11) for `array` and `forward_list`, others stay unchanged)
m (Example: +<compare>)
 
(8 intermediate revisions by 3 users not shown)
Line 1: Line 1:
{{title|1=operator==,!=,<,<=,>,>=,<=>{{small|(std::{{{1}}})}}}}
+
{{#vardefine:cont|{{{1|vector}}}}}<!--
{{cpp/container/{{{1|}}}/navbar}}
+
-->{{title|1=operator==,!=,<,<=,>,>=,<=>{{petty|(std::{{#var:cont}})}}}}
{{cpp/container/get_types|{{{1|}}}}}
+
{{cpp/container/{{#var:cont}}/navbar}}
 +
{{cpp/container/get_types|{{#var:cont}}}}
 
{{dcl begin}}
 
{{dcl begin}}
{{dcl header|{{cpp/container/get_header|{{{1}}}}}}}
+
{{dcl header|{{cpp/container/get_header|{{#var:cont}}}}}}
{{#switch:{{{1}}}|array|vector=
+
{{#switch:{{#var:cont}}
{{dcl rev multi|num=1
+
|array|vector=
|until1=c++20|dcl1=
+
{{dcl|num=1|since={{cpp/std|{{#var:cont}}}}|notes={{mark constexpr since c++20}}|1=
template< {{#var:types}} >
+
bool operator==( const std::{{{1}}}<{{#var:types_short}}>& lhs,
+
                const std::{{{1}}}<{{#var:types_short}}>& rhs );
+
|dcl2=
+
 
template< {{#var:types}} >
 
template< {{#var:types}} >
constexpr bool operator==( const std::{{{1}}}<{{#var:types_short}}>& lhs,
+
bool operator==( const std::{{#var:cont}}<{{#var:types_short}}>& lhs,
                          const std::{{{1}}}<{{#var:types_short}}>& rhs );
+
                const std::{{#var:cont}}<{{#var:types_short}}>& rhs );
 
}}
 
}}
 
|#default=
 
|#default=
{{dcl|num=1|since={{cpp/std|{{{1|}}}}}|1=
+
{{dcl|num=1|since={{cpp/std|{{#var:cont}}}}|1=
 
template< {{#var:types}} >
 
template< {{#var:types}} >
bool operator==( const std::{{{1}}}<{{#var:types_short}}>& lhs,
+
bool operator==( const std::{{#var:cont}}<{{#var:types_short}}>& lhs,
                 const std::{{{1}}}<{{#var:types_short}}>& rhs );
+
                 const std::{{#var:cont}}<{{#var:types_short}}>& rhs );
 
}}
 
}}
 
}}
 
}}
{{dcl|num=2|since={{cpp/std|{{{1|}}}}}|until=c++20|1=
+
{{dcl|num=2|since={{cpp/std|{{#var:cont}}}}|until=c++20|1=
 
template< {{#var:types}} >
 
template< {{#var:types}} >
bool operator!=( const std::{{{1}}}<{{#var:types_short}}>& lhs,
+
bool operator!=( const std::{{#var:cont}}<{{#var:types_short}}>& lhs,
                 const std::{{{1}}}<{{#var:types_short}}>& rhs );
+
                 const std::{{#var:cont}}<{{#var:types_short}}>& rhs );
 
}}
 
}}
{{dcl|num=3|since={{cpp/std|{{{1|}}}}}|until=c++20|1=
+
{{dcl|num=3|since={{cpp/std|{{#var:cont}}}}|until=c++20|1=
 
template< {{#var:types}} >
 
template< {{#var:types}} >
bool operator<( const std::{{{1}}}<{{#var:types_short}}>& lhs,
+
bool operator<( const std::{{#var:cont}}<{{#var:types_short}}>& lhs,
                 const std::{{{1}}}<{{#var:types_short}}>& rhs );
+
                 const std::{{#var:cont}}<{{#var:types_short}}>& rhs );
 
}}
 
}}
{{dcl|num=4|since={{cpp/std|{{{1|}}}}}|until=c++20|1=
+
{{dcl|num=4|since={{cpp/std|{{#var:cont}}}}|until=c++20|1=
 
template< {{#var:types}} >
 
template< {{#var:types}} >
bool operator<=( const std::{{{1}}}<{{#var:types_short}}>& lhs,
+
bool operator<=( const std::{{#var:cont}}<{{#var:types_short}}>& lhs,
                 const std::{{{1}}}<{{#var:types_short}}>& rhs );
+
                 const std::{{#var:cont}}<{{#var:types_short}}>& rhs );
 
}}
 
}}
{{dcl|num=5|since={{cpp/std|{{{1|}}}}}|until=c++20|1=
+
{{dcl|num=5|since={{cpp/std|{{#var:cont}}}}|until=c++20|1=
 
template< {{#var:types}} >
 
template< {{#var:types}} >
bool operator>( const std::{{{1}}}<{{#var:types_short}}>& lhs,
+
bool operator>( const std::{{#var:cont}}<{{#var:types_short}}>& lhs,
                 const std::{{{1}}}<{{#var:types_short}}>& rhs );
+
                 const std::{{#var:cont}}<{{#var:types_short}}>& rhs );
 
}}
 
}}
{{dcl|num=6|since={{cpp/std|{{{1|}}}}}|until=c++20|1=
+
{{dcl|num=6|since={{cpp/std|{{#var:cont}}}}|until=c++20|1=
 
template< {{#var:types}} >
 
template< {{#var:types}} >
bool operator>=( const std::{{{1}}}<{{#var:types_short}}>& lhs,
+
bool operator>=( const std::{{#var:cont}}<{{#var:types_short}}>& lhs,
                 const std::{{{1}}}<{{#var:types_short}}>& rhs );
+
                 const std::{{#var:cont}}<{{#var:types_short}}>& rhs );
 
}}
 
}}
 
{{dcl|num=7|since=c++20|1=
 
{{dcl|num=7|since=c++20|1=
 
template< {{#var:types}} >
 
template< {{#var:types}} >
{{#switch:{{{1}}}
+
{{#switch:{{#var:cont}}
 
|array|vector=
 
|array|vector=
constexpr /* see below */ operator<=>( const std::{{{1}}}<{{#var:types_short}}>& lhs,
+
constexpr synth-three-way-result<T>
                                      const std::{{{1}}}<{{#var:types_short}}>& rhs );
+
    operator<=>( const std::{{#var:cont}}<{{#var:types_short}}>& lhs,
 +
                const std::{{#var:cont}}<{{#var:types_short}}>& rhs );
 
|#default=
 
|#default=
/* see below */ operator<=>( const std::{{{1}}}<{{#var:types_short}}>& lhs,
+
synth-three-way-result<T>
                            const std::{{{1}}}<{{#var:types_short}}>& rhs );}}  
+
    operator<=>( const std::{{#var:cont}}<{{#var:types_short}}>& lhs,
 +
                const std::{{#var:cont}}<{{#var:types_short}}>& rhs );}}
 
}}
 
}}
 
{{dcl end}}
 
{{dcl end}}
  
Compares the contents of two {{tt|{{{1}}}}}s.
+
Compares the contents of two {{tt|{{#var:cont}}}}s.
  
 
@1,2@ Checks if the contents of {{c|lhs}} and {{c|rhs}} are equal, that is, they have the same number of elements and each element in {{c|lhs}} compares equal with the element in {{c|rhs}} at the same position.
 
@1,2@ Checks if the contents of {{c|lhs}} and {{c|rhs}} are equal, that is, they have the same number of elements and each element in {{c|lhs}} compares equal with the element in {{c|rhs}} at the same position.
  
@3-6@ Compares the contents of {{c|lhs}} and {{c|rhs}} lexicographically. The comparison is performed by a function equivalent to {{lc|std::lexicographical_compare}}. {{cpp/container/if ord|{{{1}}}|This comparison ignores the {{tt|{{{1}}}}}'s ordering {{spar|Compare}}.}}
+
@3-6@ Compares the contents of {{c|lhs}} and {{c|rhs}} lexicographically. The comparison is performed by a function equivalent to {{lc|std::lexicographical_compare}}. {{cpp/container/if ord|{{#var:cont}}|This comparison ignores the {{tt|{{#var:cont}}}}'s ordering {{spar|Compare}}.}}
  
@7@ Compares the contents of {{c|lhs}} and {{c|rhs}} lexicographically. The comparison is performed as if by calling {{lc|std::lexicographical_compare_three_way}} on two {{tt|{{{1}}}}}s with a function object performing ''synthesized three-way comparison'' (see below). The return type is same as the result type of synthesized three-way comparison. {{cpp/container/if ord|{{{1}}}|This comparison ignores the {{tt|{{{1}}}}}'s ordering {{spar|Compare}}.}}
+
@7@ Compares the contents of {{c|lhs}} and {{c|rhs}} lexicographically. The comparison is performed as if by calling {{box|{{c/core|std::lexicographical_compare_three_way(lhs.begin(), lhs.end(),}}<br>{{nbspt|39}}{{c/core|rhs.begin(), rhs.end(),}}{{nbspt}}{{lti|cpp/standard library/synth-three-way}}{{c/core|)}}}}.{{cpp/container/if ord|{{#var:cont}}| This comparison ignores the {{tt|{{#var:cont}}}}'s ordering {{spar|Compare}}.}}
Given two {{c/core|const E}} lvalues {{c|lhs}} and {{c|rhs}} as left hand operand and right hand operand respectively (where {{tt|E}} is {{#switch:{{{1}}}
+
@@ The return type is the return type of {{lti|cpp/standard library/synth-three-way}} (i.e., {{lti|cpp/standard library/synth-three-way|synth-three-way-result}}{{sep}}{{c/core|<T>}}).
|map|multimap={{c/core|std::pair<const Key, T>}}
+
@@ If none of the following conditions is satisfied, the behavior is undefined:
|set|multiset={{tt|Key}}
+
* {{tt|T}} models {{lconcept|three_way_comparable}}.
|{{tt|T}}}}), ''synthesized three-way comparison'' is defined as:
+
* {{tt|<}} is defined for values of type (possibly const-qualified) {{tt|T}}, and {{tt|<}} is a total ordering relationship.
* if {{c|std::three_way_comparable_with<E, E>}} is satisfied, equivalent to {{c|1=lhs <=> rhs}};
+
* otherwise, if comparing two {{c/core|const E}} lvalues by {{c/core|operator<}} is well-formed and the result type satisfies ''{{lconcept|boolean-testable}}'', equivalent to
+
{{source|
+
lhs < rhs ? std::weak_ordering::less :
+
rhs < lhs ? std::weak_ordering::greater :
+
            std::weak_ordering::equivalent}}
+
* otherwise, synthesized three-way comparison is not defined, and {{c/core|1=operator<=>}} does not participate in overload resolution.
+
The behavior of {{c/core|1=operator<=>}} is undefined if {{lconcept|three_way_comparable_with}} or ''{{lconcept|boolean-testable}}'' is satisfied but not modeled, or {{c/core|operator<}} is used but {{tt|E}} and {{tt|<}} do not establish a total order.
+
  
 
{{rrev|since=c++20|
 
{{rrev|since=c++20|
Line 85: Line 76:
 
===Parameters===
 
===Parameters===
 
{{par begin}}
 
{{par begin}}
{{par|lhs, rhs|{{tt|{{{1}}}}}s whose contents to compare}} {{#switch:{{{1|}}}  
+
{{par|lhs, rhs|{{tt|{{#var:cont}}}}s whose contents to compare}} {{#switch:{{#var:cont}}
 
|array|vector|deque|list|forward_list=
 
|array|vector|deque|list|forward_list=
 
{{par req named|T|EqualityComparable|overloads=1,2}}
 
{{par req named|T|EqualityComparable|overloads=1,2}}
Line 94: Line 85:
 
{{par req named|T, Key|EqualityComparable|overloads=1,2}}
 
{{par req named|T, Key|EqualityComparable|overloads=1,2}}
 
{{par req named|Key|LessThanComparable|overloads=3-6|notes=The ordering relation must establish total order.}}
 
{{par req named|Key|LessThanComparable|overloads=3-6|notes=The ordering relation must establish total order.}}
|{{included}}  
+
|{{included}}
 
}}
 
}}
{{par end}}  
+
{{par end}}
  
 
===Return value===
 
===Return value===
@1@ {{c|true}} if the contents of the {{tt|{{{1}}}}}s are equal, {{c|false}} otherwise.
+
@1@ {{c|true}} if the contents of the {{tt|{{#var:cont}}}}s are equal, {{c|false}} otherwise.
  
@2@ {{c|true}} if the contents of the {{tt|{{{1}}}}}s are not equal, {{c|false}} otherwise.
+
@2@ {{c|true}} if the contents of the {{tt|{{#var:cont}}}}s are not equal, {{c|false}} otherwise.
  
 
@3@ {{c|true}} if the contents of the {{c|lhs}} are lexicographically ''less'' than the contents of {{c|rhs}}, {{c|false}} otherwise.
 
@3@ {{c|true}} if the contents of the {{c|lhs}} are lexicographically ''less'' than the contents of {{c|rhs}}, {{c|false}} otherwise.
Line 114: Line 105:
  
 
===Complexity===
 
===Complexity===
{{#switch:{{{1}}}|array|forward_list=Linear in the size of the {{tt|{{{1}}}}}.
+
{{#switch:{{#var:cont}}|array|forward_list=Linear in the size of the {{tt|{{#var:cont}}}}.
 
|#default=
 
|#default=
@1,2@ Constant if {{c|lhs}} and {{c|rhs}} are of different size, otherwise linear in the size of the {{tt|{{{1}}}}}.
+
@1,2@ Constant if {{c|lhs}} and {{c|rhs}} are of different size, otherwise linear in the size of the {{tt|{{#var:cont}}}}.
@3-7@ Linear in the size of the {{tt|{{{1}}}}}.
+
@3-7@ Linear in the size of the {{tt|{{#var:cont}}}}.
 +
}}
 +
 
 +
===Notes===
 +
{{rrev multi|rev1=
 +
The relational operators are defined in terms of the element type's {{c/core|operator<}}.
 +
|since2=c++20|rev2=
 +
The relational operators are defined in terms of {{lti|cpp/standard library/synth-three-way}}, which uses {{c/core|1=operator<=>}} if possible, or {{c/core|operator<}} otherwise.
 +
 
 +
Notably, if the element does not itself provide {{c/core|1=operator<=>}}, but is implicitly convertible to a three-way comparable type, that conversion will be used instead of {{c/core|operator<}}.
 
}}
 
}}
  
 
===Example===
 
===Example===
 
<!--temp set container to test code below-->
 
<!--temp set container to test code below-->
{{#vardefine:container|{{{1|forward_list}}}}}
+
{{#vardefine:container|{{#var:cont}}}}
  
 
{{#vardefine:headers|
 
{{#vardefine:headers|
 
#include <cassert>
 
#include <cassert>
 +
#include <compare>
 
#include <{{Template:cpp/container/get header|{{#var:container}}}}>
 
#include <{{Template:cpp/container/get header|{{#var:container}}}}>
 
}}
 
}}
Line 191: Line 192:
 
     std::{{#var:container}}<int, char> b{<!---->{1, 'a'}, {2, 'b'}, {3, 'c'}<!---->};
 
     std::{{#var:container}}<int, char> b{<!---->{1, 'a'}, {2, 'b'}, {3, 'c'}<!---->};
 
     std::{{#var:container}}<int, char> c{<!---->{7, 'Z'}, {8, 'Y'}, {9, 'X'}, {10, 'W'}<!---->};
 
     std::{{#var:container}}<int, char> c{<!---->{7, 'Z'}, {8, 'Y'}, {9, 'X'}, {10, 'W'}<!---->};
   
+
 
 
     {{#var:common_body}}
 
     {{#var:common_body}}
 
}
 
}
Line 197: Line 198:
 
}}
 
}}
  
{{#switch:{{{1|}}}
 
|vector=
 
 
===Defect reports===
 
===Defect reports===
 
{{dr list begin}}
 
{{dr list begin}}
 +
{{#ifeq:{{#var:cont}}
 +
|vector=
 
{{dr list item|wg=lwg|dr=469|std=C++98|before={{ltt|cpp/container/vector bool|std::vector<bool>}} specialized the comparison operators|after=removed the specializations}}
 
{{dr list item|wg=lwg|dr=469|std=C++98|before={{ltt|cpp/container/vector bool|std::vector<bool>}} specialized the comparison operators|after=removed the specializations}}
{{dr list end}}
 
 
}}
 
}}
 +
{{dr list item|wg=lwg|dr=3431|std=C++20|before={{c/core|1=operator<=>}} did not require {{tt|T}}<br>to model {{lconcept|three_way_comparable}}|after=requires}}
 +
{{dr list end}}

Latest revision as of 03:05, 29 August 2024

 
 
 
 
Defined in header <vector>
template< class T, class Alloc >

bool operator==( const std::vector<T, Alloc>& lhs,

                 const std::vector<T, Alloc>& rhs );
(1) (constexpr since C++20)
template< class T, class Alloc >

bool operator!=( const std::vector<T, Alloc>& lhs,

                 const std::vector<T, Alloc>& rhs );
(2) (until C++20)
template< class T, class Alloc >

bool operator<( const std::vector<T, Alloc>& lhs,

                const std::vector<T, Alloc>& rhs );
(3) (until C++20)
template< class T, class Alloc >

bool operator<=( const std::vector<T, Alloc>& lhs,

                 const std::vector<T, Alloc>& rhs );
(4) (until C++20)
template< class T, class Alloc >

bool operator>( const std::vector<T, Alloc>& lhs,

                const std::vector<T, Alloc>& rhs );
(5) (until C++20)
template< class T, class Alloc >

bool operator>=( const std::vector<T, Alloc>& lhs,

                 const std::vector<T, Alloc>& rhs );
(6) (until C++20)
template< class T, class Alloc >

constexpr synth-three-way-result<T>
    operator<=>( const std::vector<T, Alloc>& lhs,

                 const std::vector<T, Alloc>& rhs );
(7) (since C++20)

Compares the contents of two vectors.

1,2) Checks if the contents of lhs and rhs are equal, that is, they have the same number of elements and each element in lhs compares equal with the element in rhs at the same position.
3-6) Compares the contents of lhs and rhs lexicographically. The comparison is performed by a function equivalent to std::lexicographical_compare.
7) Compares the contents of lhs and rhs lexicographically. The comparison is performed as if by calling std::lexicographical_compare_three_way(lhs.begin(), lhs.end(),
                                       rhs.begin(), rhs.end(), synth-three-way)
.
The return type is the return type of synth-three-way (i.e., synth-three-way-result <T>).
If none of the following conditions is satisfied, the behavior is undefined:
  • T models three_way_comparable.
  • < is defined for values of type (possibly const-qualified) T, and < is a total ordering relationship.

The <, <=, >, >=, and != operators are synthesized from operator<=> and operator== respectively.

(since C++20)

Contents

[edit] Parameters

lhs, rhs - vectors whose contents to compare
-
T must meet the requirements of EqualityComparable in order to use overloads (1,2).
-
T must meet the requirements of LessThanComparable in order to use overloads (3-6). The ordering relation must establish total order.

[edit] Return value

1) true if the contents of the vectors are equal, false otherwise.
2) true if the contents of the vectors are not equal, false otherwise.
3) true if the contents of the lhs are lexicographically less than the contents of rhs, false otherwise.
4) true if the contents of the lhs are lexicographically less than or equal to the contents of rhs, false otherwise.
5) true if the contents of the lhs are lexicographically greater than the contents of rhs, false otherwise.
6) true if the contents of the lhs are lexicographically greater than or equal to the contents of rhs, false otherwise.
7) The relative order of the first pair of non-equivalent elements in lhs and rhs if there are such elements, lhs.size() <=> rhs.size() otherwise.

[edit] Complexity

1,2) Constant if lhs and rhs are of different size, otherwise linear in the size of the vector.
3-7) Linear in the size of the vector.

[edit] Notes

The relational operators are defined in terms of the element type's operator<.

(until C++20)

The relational operators are defined in terms of synth-three-way, which uses operator<=> if possible, or operator< otherwise.

Notably, if the element does not itself provide operator<=>, but is implicitly convertible to a three-way comparable type, that conversion will be used instead of operator<.

(since C++20)

[edit] Example

#include <cassert>
#include <compare>
#include <vector>
 
int main()
{
    const std::vector
        a{1, 2, 3},
        b{1, 2, 3},
        c{7, 8, 9, 10};
 
    assert
    (""
        "Compare equal containers:" &&
        (a != b) == false &&
        (a == b) == true &&
        (a < b) == false &&
        (a <= b) == true &&
        (a > b) == false &&
        (a >= b) == true &&
        (a <=> b) != std::weak_ordering::less &&
        (a <=> b) != std::weak_ordering::greater &&
        (a <=> b) == std::weak_ordering::equivalent &&
        (a <=> b) >= 0 &&
        (a <=> b) <= 0 &&
        (a <=> b) == 0 &&
 
        "Compare non equal containers:" &&
        (a != c) == true &&
        (a == c) == false &&
        (a < c) == true &&
        (a <= c) == true &&
        (a > c) == false &&
        (a >= c) == false &&
        (a <=> c) == std::weak_ordering::less &&
        (a <=> c) != std::weak_ordering::equivalent &&
        (a <=> c) != std::weak_ordering::greater &&
        (a <=> c) < 0 &&
        (a <=> c) != 0 &&
        (a <=> c) <= 0 &&
    "");
}

[edit] Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Correct behavior
LWG 3431 C++20 operator<=> did not require T
to model three_way_comparable
requires