A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://en.cppreference.com/w/cpp/language/../language/operator_comparison.html below:

Comparison operators - cppreference.com

Compares the arguments.

Operator name  Syntax  Overloadable Prototype examples (for class T) Inside class definition Outside class definition Equal to a == b Yes bool T::operator==(const U& b) const; bool operator==(const T& a, const U& b); Not equal to a != b Yes bool T::operator!=(const U& b) const; bool operator!=(const T& a, const U& b); Less than a < b Yes bool T::operator<(const U& b) const; bool operator<(const T& a, const U& b); Greater than a > b Yes bool T::operator>(const U& b) const; bool operator>(const T& a, const U& b); Less than or equal to a <= b Yes bool T::operator<=(const U& b) const; bool operator<=(const T& a, const U& b); Greater than or equal to a >= b Yes bool T::operator>=(const U& b) const; bool operator>=(const T& a, const U& b); Three-way comparison (C++20) a <=> b Yes T::operator<=>(const U& b) const;[1] operator<=>(const T& a, const U& b);[1]
Notes
  1. ↑ 1.0 1.1 R is the return type of operator<=> (see below)
[edit] Two-way comparison

The two-way comparison operator expressions have the form

[edit] Relational operators lhs < rhs (1) lhs > rhs (2) lhs <= rhs (3) lhs >= rhs (4) [edit] Equality operators lhs == rhs (5) lhs != rhs (6)

1) Returns true if lhs is less than rhs, false otherwise.

2) Returns true if lhs is greater than rhs, false otherwise.

3) Returns true if lhs is less than or equal to rhs, false otherwise.

4) Returns true if lhs is greater than or equal to rhs, false otherwise.

5) Returns true if lhs is equal to rhs, false otherwise.

6) Returns true if lhs is not equal to rhs, false otherwise.

[edit] Built-in two-way comparison operators

For built-in two-way comparison operators, lvalue-to-rvalue conversions, array-to-pointer conversions(until C++26) and function-to-pointer conversions are applied to lhs and rhs .

The comparison is deprecated if both lhs and rhs have array type prior to the application of these conversions.

(since C++20)
(until C++26)

For built-in relational operators, if one of the operands is a pointer, the array-to-pointer conversion is performed on the other operand.

For built-in equality operators, if one of the operands is a pointer or a null pointer constant, the array-to-pointer conversion is performed on the other operand.

(since C++26)

For built-in two-way comparison operators, the result is a bool prvalue.

[edit] Built-in arithmetic comparison

If the converted operands both have arithmetic or enumeration type (scoped or unscoped), usual arithmetic conversions are performed on both operands. The values are compared after conversions:

#include <iostream>
 
int main()
{
    static_assert(sizeof(unsigned char) < sizeof(int),
                  "Cannot compare signed and smaller unsigned properly");
    int a = -1;
    int b = 1;
    unsigned int c = 1;
    unsigned char d = 1;
 
    std::cout << std::boolalpha
              << "Comparing two signed values:\n"
                 " -1 == 1 ? " << (a == b) << "\n"
                 " -1 <  1 ? " << (a <  b) << "\n"
                 " -1 >  1 ? " << (a >  b) << "\n"
                 "Comparing signed and unsigned:\n"
                 // may issue different-signedness warning:
                 " -1 == 1 ? " << (a == c) << "\n"
                 // may issue different-signedness warning:
                 " -1 <  1 ? " << (a <  c) << "\n"
                 // may issue different-signedness warning:
                 " -1 >  1 ? " << (a >  c) << "\n"
                 "Comparing signed and smaller unsigned:\n"
                 " -1 == 1 ? " << (a == d) << "\n"
                 " -1 <  1 ? " << (a <  d) << "\n"
                 " -1 >  1 ? " << (a >  d) << '\n';
}

Output:

Comparing two signed values:
 -1 == 1 ? false
 -1 <  1 ? true
 -1 >  1 ? false
Comparing signed and unsigned:
 -1 == 1 ? false
 -1 <  1 ? false
 -1 >  1 ? true
Comparing signed and smaller unsigned:
 -1 == 1 ? false
 -1 <  1 ? true
 -1 >  1 ? false
[edit] Built-in pointer equality comparison

The converted operands of equality operators == and != can also have the type std::nullptr_t,(since C++11) pointer type or pointer-to-member type.

Built-in pointer equality comparison has three possible results: equal, unequal and unspecified. The values yielded by equality operators for built-in pointer equality comparison is listed below:

 Comparison result 
of p and q Value yielded by p == q p != q equal true false unequal false true unspecified  unspecified bool value 

If at least one of converted lhs and rhs is a pointer, pointer conversions, function pointer conversions(since C++17) and qualification conversions are performed on both converted operands to bring them to their composite pointer type. The two pointers of the composite pointer type are compared as follows:

the result of the comparison is unspecified.

If at least one of converted lhs and rhs is a pointer to member, pointer-to-member conversions, function pointer conversions(since C++17) and qualification conversions are performed on both converted operands to bring them to their composite pointer type. The two pointers to members of the composite pointer type are compared as follows:

struct P {};
struct Q : P { int x; };
struct R : P { int x; };
 
int P::*bx = (int(P::*)) &Q::x;
int P::*cx = (int(P::*)) &R::x;
 
bool b1 = (bx == cx); // unspecified
 
struct B
{
    int f();
};
struct L : B {};
struct R : B {};
struct D : L, R {};
 
int (B::*pb)() = &B::f;
int (L::*pl)() = pb;
int (R::*pr)() = pb;
int (D::*pdl)() = pl;
int (D::*pdr)() = pr;
 
bool x = (pdl == pdr); // false
bool y = (pb == pl);   // true

Two operands of type std::nullptr_t or one operand of type std::nullptr_t and the other a null pointer constant compare equal.

(since C++11) [edit] Built-in pointer relational comparison

The converted operands of relational operators >, <, >= and <= can also have pointer type.

Built-in pointer relational comparison on unequal pointers p and q has three possible results: p is greater, q is greater and unspecified. The values yielded by relational operators for built-in pointer relational comparison is listed below:

 Comparison result 
of p and q Value yielded by  p > q   p < q   p >= q   p <= q  equal false false true true p is greater true false true false q is greater false true false true unspecified unspecified bool value

If converted lhs and rhs are both pointers, pointer conversions, function pointer conversions(since C++17) and qualification conversions are performed on both converted operands to bring them to their composite pointer type. The two pointers of the composite pointer type are compared as follows:

[edit] Pointer total order

There exists an implementation-defined strict total order over pointers in each program. The strict total order is consistent with the partial order described above: unspecified results become implementation-defined, while other results stay the same.

Pointer comparison with the strict total order is applied in the following cases:

[edit] Overloads

In overload resolution against user-defined operators, for every pair of promoted arithmetic types L and R, including enumeration types, the following function signatures participate in overload resolution:

bool operator<(L, R);

bool operator>(L, R);

bool operator<=(L, R);

bool operator>=(L, R);

bool operator==(L, R);

bool operator!=(L, R);

For every type P which is either pointer to object or pointer to function, the following function signatures participate in overload resolution:

bool operator<(P, P);

bool operator>(P, P);

bool operator<=(P, P);

bool operator>=(P, P);

bool operator==(P, P);

bool operator!=(P, P);

For every type MP that is a pointer to member object or pointer to member function or std::nullptr_t(since C++11), the following function signatures participate in overload resolution:

bool operator==(MP, MP);

bool operator!=(MP, MP);

#include <iostream>
 
struct Foo
{
    int n1;
    int n2;
};
 
union Union
{
    int n;
    double d;
};
 
int main()
{
    std::cout << std::boolalpha;
 
    char a[4] = "abc";
    char* p1 = &a[1];
    char* p2 = &a[2];
    std::cout << "Pointers to array elements:\n"
              << "p1 == p2? " << (p1 == p2) << '\n'
              << "p1 <  p2? " << (p1 <  p2) << '\n';
 
    Foo f;
    int* p3 = &f.n1;
    int* p4 = &f.n2;
    std::cout << "Pointers to members of a class:\n"
              << "p3 == p4? " << (p3 == p4) << '\n'
              << "p3 <  p4? " << (p3 <  p4) << '\n';
 
    Union u;
    int* p5 = &u.n;
    double* p6 = &u.d;
    std::cout << "Pointers to members of a union:\n"
              << "p5 == (void*)p6? " << (p5 == (void*)p6) << '\n'
              << "p5 <  (void*)p6? " << (p5 <  (void*)p6) << '\n';
}

Output:

Pointers to array elements:
p1 == p2? false
p1 <  p2? true
Pointers to members of a class:
p3 == p4? false
p3 <  p4? true
Pointers to members of a union:
p5 == (void*)p6? true
p5 <  (void*)p6? false
Three-way comparison

The three-way comparison operator expressions have the form

The expression returns an object such that

If one of the operands is of type bool and the other is not, the program is ill-formed.

If both operands have arithmetic types, or if one operand has unscoped enumeration type and the other has integral type, the usual arithmetic conversions are applied to the operands, and then

If both operands have the same enumeration type E, the operator yields the result of converting the operands to the underlying type of E and applying <=> to the converted operands.

If at least one of the operands is a pointer to object or pointer to member, array-to-pointer conversions, pointer conversions and qualification conversions are applied to both operands to bring them to their composite pointer type.

For converted pointer operands p and q, p <=> q returns a prvalue of type std::strong_ordering:

Otherwise, the program is ill-formed.

Overloads

In overload resolution against user-defined operators, for pointer or enumeration type T, the following function signature participates in overload resolution:

Where R is the ordering category type defined above.

#include <compare>
#include <iostream>
 
int main()
{
    double foo = -0.0;
    double bar = 0.0;
 
    auto res = foo <=> bar;
 
    if (res < 0)
        std::cout << "-0 is less than 0";
    else if (res > 0)
        std::cout << "-0 is greater than 0";
    else if (res == 0)
        std::cout << "-0 and 0 are equal";
    else
        std::cout << "-0 and 0 are unordered";
}

Output:

(since C++20) [edit] Notes

Because comparison operators group left-to-right, the expression a < b < c is parsed (a < b) < c, and not a < (b < c) or (a < b) && (b < c).

#include <iostream>
 
int main()
{
    int a = 3, b = 2, c = 1;
 
    std::cout << std::boolalpha
        << (a < b < c) << '\n' // true; maybe warning
        << ((a < b) < c) << '\n' // true
        << (a < (b < c)) << '\n' // false
        << ((a < b) && (b < c)) << '\n'; // false
}

A common requirement for user-defined operator< is strict weak ordering. In particular, this is required by the standard algorithms and containers that work with Compare types: std::sort, std::max_element, std::map, etc.

The comparison result of pointers to different non-static data members of the same class implies that non-static data members in each of the three member access modes(until C++23) are positioned in memory in order of declaration.

Although the results of comparing pointers of random origin (e.g. not all pointing to members of the same array) is unspecified, many implementations provide strict total ordering of pointers, e.g. if they are implemented as addresses within continuous virtual address space. Those implementations that do not (e.g. where not all bits of the pointer are part of a memory address and have to be ignored for comparison, or an additional calculation is required or otherwise pointer and integer is not a 1 to 1 relationship), provide a specialization of std::less for pointers that has that guarantee. This makes it possible to use all pointers of random origin as keys in standard associative containers such as std::set or std::map.

For the types that are both EqualityComparable and LessThanComparable, the C++ standard library makes a distinction between equality, which is the value of the expression a == b and equivalence, which is the value of the expression !(a < b) && !(b < a).

Comparison between pointers and null pointer constants was removed by the resolution of CWG issue 583 included in N3624:

void f(char* p)
{
    if (p > 0) { /*...*/ } // Error with N3624, compiled before N3624
    if (p > nullptr) { /*...*/ } // Error with N3624, compiled before N3624
}
 
int main() {}

Three-way comparison can be automatically generated for class types, see default comparisons.

If both of the operands are arrays, three-way comparison is ill-formed.

unsigned int i = 1;
auto r = -1 < i;    // existing pitfall: returns ‘false’
auto r2 = -1 <=> i; // Error: narrowing conversion required
[edit] Standard library

Comparison operators are overloaded for many classes in the standard library.

The namespace std::rel_ops provides generic operators !=, >, <=, and >=:

[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 CWG 583
(N3624) C++98 all six comparison operators could be used to
compare a pointer with a null pointer constant only equality operators
are allowed CWG 661 C++98 the actual semantics of arithmetic comparisons (e.g.
whether 1 < 2 yields true or false) were unspecified specification added CWG 879 C++98 pointers to function types and pointers
to void did not have built-in comparisons added comparison
specification for these pointers CWG 1596 C++98 non-array objects were considered to belong to arrays with
one element only for the purpose of pointer arithmetic the rule is also
applied to comparison CWG 1598 C++98 two pointers to members of classes that are different and
neither is the base class of the other did not compare equal
even if the offsets of the pointed members can be the same the result is
unspecified
in this case CWG 1858 C++98 it was not clear whether two pointers to members
that refer to different members of the same union
compare equal as if they refer to the same member they compare
equal in this case CWG 2419 C++98 a pointer to non-array object was only treated as a
pointer to the first element of an array with size 1
in pointer comparison if the pointer is obtained by & applies to all pointers
to non-array objects CWG 2526 C++98 the definition of relational comparison (>, >=, < and <=) of
pointers to void and function pointers were removed by N3624 restored CWG 2796 C++17 function pointer conversions were not performed on the converted
pointer operands during built-in pointer relational comparisons performs these
conversions in this case [edit] See also Common operators assignment increment
decrement
arithmetic logical comparison member
access
other

a = b
a += b
a -= b
a *= b
a /= b
a %= b
a &= b
a |= b
a ^= b
a <<= b
a >>= b

++a
--a
a++
a--

+a
-a
a + b
a - b
a * b
a / b
a % b
~a
a & b
a | b
a ^ b
a << b
a >> b

!a
a && b
a || b

a == b
a != b
a < b
a > b
a <= b
a >= b
a <=> b

a[...]
*a
&a
a->b
a.b
a->*b
a.*b

function call

a(...)

comma

a, b

conditional

a ? b : c

Special operators

static_cast converts one type to another related type
dynamic_cast converts within inheritance hierarchies
const_cast adds or removes cv-qualifiers
reinterpret_cast converts type to unrelated type
C-style cast converts one type to another by a mix of static_cast, const_cast, and reinterpret_cast
new creates objects with dynamic storage duration
delete destructs objects previously created by the new expression and releases obtained memory area
sizeof queries the size of a type
sizeof... queries the size of a pack (since C++11)
typeid queries the type information of a type
noexcept checks if an expression can throw an exception (since C++11)
alignof queries alignment requirements of a type (since C++11)


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4