Namespaces
Variants
Views
Actions

Comparison operators

From cppreference.com
< cpp‎ | language
Revision as of 21:48, 2 November 2012 by P12bot (Talk | contribs)

 
 
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements
Jump statements
Functions
function declaration
lambda function declaration
function template
inline specifier
exception specifications (deprecated)
noexcept specifier (C++11)
Exceptions
Namespaces
Types
decltype specifier (C++11)
Specifiers
cv specifiers
storage duration specifiers
constexpr specifier (C++11)
auto specifier (C++11)
alignas specifier (C++11)
Initialization
Literals
Expressions
alternative representations
Utilities
Types
typedef declaration
type alias declaration (C++11)
attributes (C++11)
Casts
implicit conversions
const_cast conversion
static_cast conversion
dynamic_cast conversion
reinterpret_cast conversion
C-style and functional cast
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
class template
function template
template specialization
parameter packs (C++11)
Miscellaneous
Inline assembly
 

Compares the arguments.

Operator name Syntax Over​load​able Prototype examples (for class T)
Inside class definition Outside class definition
equal to a == b Yes bool T::operator ==(const T2 &b) const; bool operator ==(const T &a, const T2 &b);
not equal to a != b Yes bool T::operator !=(const T2 &b) const; bool operator !=(const T &a, const T2 &b);
less than a < b Yes bool T::operator <(const T2 &b) const; bool operator <(const T &a, const T2 &b);
greater than a > b Yes bool T::operator >(const T2 &b) const; bool operator >(const T &a, const T2 &b);
less than or equal to a <= b Yes bool T::operator <=(const T2 &b) const; bool operator <=(const T &a, const T2 &b);
greater than or equal to a >= b Yes bool T::operator >=(const T2 &b) const; bool operator >=(const T &a, const T2 &b);
Notes
  • All built-in operators return bool, and most user-defined overloads also return bool so that the user-defined operators can be used in the same manner as the built-ins. However, in a user-defined operator overload, any type can be used as return type (including void).
  • T2 can be any type including T

Contents

Explanation

Returns the boolean result of comparison of the values of the arguments, which are not modified.

Arithmetic comparison operators

For every pair of promoted arithmetic types L and R, including enumeration types, the following function signatures participate in overload resolution: Template:ddcl list begin <tr class="t-dcl ">

<td class="t-dcl-nopad">
bool operator<(L, R);
</td>

<td class="t-dcl-nopad"> </td> <td class="t-dcl-nopad"> </td> </tr> <tr class="t-dcl ">

<td class="t-dcl-nopad">
bool operator>(L, R);
</td>

<td class="t-dcl-nopad"> </td> <td class="t-dcl-nopad"> </td> </tr> <tr class="t-dcl ">

<td class="t-dcl-nopad">
bool operator<=(L, R);
</td>

<td class="t-dcl-nopad"> </td> <td class="t-dcl-nopad"> </td> </tr> <tr class="t-dcl ">

<td class="t-dcl-nopad">
bool operator>=(L, R);
</td>

<td class="t-dcl-nopad"> </td> <td class="t-dcl-nopad"> </td> </tr> <tr class="t-dcl ">

<td class="t-dcl-nopad">
bool operator==(L, R);
</td>

<td class="t-dcl-nopad"> </td> <td class="t-dcl-nopad"> </td> </tr> <tr class="t-dcl ">

<td class="t-dcl-nopad">
bool operator!=(L, R);
</td>

<td class="t-dcl-nopad"> </td> <td class="t-dcl-nopad"> </td> </tr> Template:ddcl list end If the operands has arithmetic or enumeration type (scoped or unscoped), usual arithmetic conversions are performed following the rules for arithmetic operators. The values are compared after conversions:

Example

#include <iostream>
int main()
{
    std::cout << std::boolalpha;
    int n = -1;
 
    int n2 = 1;
    std::cout << " -1 == 1? " << (n == n2) << '\n'
              << "Comparing two signed values:\n"
              << " -1  < 1? " << (n < n2) << '\n'
              << " -1  > 1? " << (n > n2) << '\n';
 
    unsigned int u = 1;
    std::cout << "Comparing signed and unsigned:\n"
              << " -1  < 1? " << (n < u) << '\n'
              << " -1  > 1? " << (n > u) << '\n';
 
    unsigned char uc = 1;
    std::cout << "Comparing signed and smaller unsigned:\n"
              << " -1  < 1? " << (n < uc) << '\n'
              << " -1  > 1? " << (n > uc) << '\n';
}

Output:

-1 == 1? false
Comparing two signed values:
 -1  < 1? true
 -1  > 1? false
Comparing signed and unsigned:
 -1  < 1? false
 -1  > 1? true
Comparing signed and smaller unsigned:
 -1  < 1? true
 -1  > 1? false

Pointer comparison operators

For every type P which is either pointer to object or pointer to function or std::nullptr_t, and for every type MP that is a pointer to member object or pointer to member function, the following function signatures participate in overload resolution: Template:ddcl list begin <tr class="t-dcl ">

<td class="t-dcl-nopad">
bool operator<(P, P);
</td>

<td class="t-dcl-nopad"> </td> <td class="t-dcl-nopad"> </td> </tr> <tr class="t-dcl ">

<td class="t-dcl-nopad">
bool operator>(P, P);
</td>

<td class="t-dcl-nopad"> </td> <td class="t-dcl-nopad"> </td> </tr> <tr class="t-dcl ">

<td class="t-dcl-nopad">
bool operator<=(P, P);
</td>

<td class="t-dcl-nopad"> </td> <td class="t-dcl-nopad"> </td> </tr> <tr class="t-dcl ">

<td class="t-dcl-nopad">
bool operator>=(P, P);
</td>

<td class="t-dcl-nopad"> </td> <td class="t-dcl-nopad"> </td> </tr> <tr class="t-dcl ">

<td class="t-dcl-nopad">
bool operator==(P, P);
</td>

<td class="t-dcl-nopad"> </td> <td class="t-dcl-nopad"> </td> </tr> <tr class="t-dcl ">

<td class="t-dcl-nopad">
bool operator!=(P, P);
</td>

<td class="t-dcl-nopad"> </td> <td class="t-dcl-nopad"> </td> </tr> <tr class="t-dcl ">

<td class="t-dcl-nopad">
bool operator==(MP, MP);
</td>

<td class="t-dcl-nopad"> </td> <td class="t-dcl-nopad"> </td> </tr> <tr class="t-dcl ">

<td class="t-dcl-nopad">
bool operator!=(MP, MP);
</td>

<td class="t-dcl-nopad"> </td> <td class="t-dcl-nopad"> </td> </tr> Template:ddcl list end Comparison operators can be used to compare two pointers (or pointers-to-members, for operator== and operator!= only), or a pointer and a null pointer constant, or two null pointer constants (but only as long as at least one of them is std::nullptr_t: comparison of NULL and NULL follows arithmetic comparison rules). Pointer conversions (pointer to member conversions if the arguments are pointers to members) and qualification conversions are applied to both operands to obtain the composite pointer type, as follows

1) If both operands are null pointer constants, the composite pointer type is std::nullptr_t
2) If one operand a null pointer constant and the other is a pointer, the composite type is exactly the pointer type
3) If both operands are pointers to the same type, with different cv-qualification, the composite is pointer to the same type with cv-qualification that is a union of the cv-qualifications of the arguments. Note that this implies that any pointer can be compared with void*.

Results of comparing two pointers (after conversions) are determined as follows:

1) If the pointers p and q
a) point to the same object or function
b) or point one past the end of the same array
c) or are both null pointers then the pointers compare equal: p==q, p<=q, and p>=q return true, while p!=q, p<q, and p>q return false,
2) If one of the operands is a null pointer and the other is not, they compare unequal: p==q returns true, p!=q returns false, the behavior of other operators is unspecified.
3) If the pointers p and q point to members of the same array a[i] and a[j] or one past the end of the array, they results of comparing the pointers is the same as the result of comparing the indexes: if i<j==true then {{{1}}}.
4) If the pointers p and q point to non-static data members within the same class or different base subobjects within the same derived class, or to their members or subobjects, recursively, and if the pointed-to members/subobjects have the same access control (e.g. both public:), and the class is not a union, then the pointer to the later declared subobject/member compares greater than the pointer to the earlier declared subobject/member. In other words, class members in each of the three access modes are positioned in memory in order of declaration.
6) If the pointers p and q point to members of the same union, they compare equal (typically an explicit conversion to void* is required for one of the operands)
7) If one of the pointers is a pointer to void and both pointers point to the same address or are both null pointers, they compare equal.
8) If two null pointer constants are compared, they compare equal.
9) If both operands are pointers to member (object or function), they compare equal if they both point to the same member of the most derived class.
10) Otherwise (if the pointers point to objects in different arrays, or to different functions, or to members of some object with different access control, etc), the results of p<q, p>q, p<=q, and p>=q are unspecified, and p!=q returns false.

Example

#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: p1 == p2 " << (p1 == p2)
              << ", p1 < p2 "  << (p1 < p2) << '\n';
 
    Foo f;
    int* p3 = &f.n1;
    int* p4 = &f.n2;
    std::cout << "Pointers to members of a class: p3 == p4 " << (p3 == p4)
              << ", p3 < p4 "  << (p3 < p4) << '\n';
 
    Union u;
    int* p5 = &u.n;
    double* p6 = &u.d;
    std::cout << "Pointers to members of a union: p5 == (void*)p6 " << (p5 == (void*)p6)
              << ", p5 < 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 < p6 false

Notes

Because these 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).

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 LessThanComparable types: std::sort, std::max_element, std::map, etc.

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.

Standard library

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

Template:cpp/memory/allocator/dcl list operator cmpTemplate:cpp/memory/unique ptr/dcl list operator cmpTemplate:cpp/memory/shared ptr/dcl list operator cmpTemplate:cpp/memory/scoped allocator adaptor/dcl list operator cmpTemplate:cpp/string/basic string/dcl list operator cmpTemplate:cpp/locale/locale/dcl list operator cmpTemplate:cpp/container/dcl list operator cmpTemplate:cpp/container/dcl list operator cmpTemplate:cpp/container/dcl list operator cmpTemplate:cpp/container/dcl list operator cmpTemplate:cpp/container/dcl list operator cmpTemplate:cpp/container/dcl list operator cmpTemplate:cpp/container/dcl list operator cmpTemplate:cpp/container/dcl list operator cmpTemplate:cpp/container/dcl list operator cmpTemplate:cpp/container/dcl list operator cmp unordTemplate:cpp/container/dcl list operator cmp unordTemplate:cpp/container/dcl list operator cmp unordTemplate:cpp/container/dcl list operator cmp unordTemplate:cpp/container/dcl list operator cmpTemplate:cpp/container/dcl list operator cmpTemplate:cpp/numeric/complex/dcl list operator cmpTemplate:cpp/numeric/valarray/dcl list operator cmpTemplate:cpp/numeric/random/engine/dcl list operator cmpTemplate:cpp/numeric/random/distribution/dcl list operator cmpTemplate:cpp/regex/dcl list operator cmp
checks whether the objects refer to the same type
(public member function of std::type_info) [edit]
compares two error_codes
(function)
compares error_conditions and error_codes
(function)
lexicographically compares the values in the pair
(function template) [edit]
lexicographically compares the values in the tuple
(function template) [edit]
compares the contents
(public member function of std::bitset) [edit]
compares an std::function with std::nullptr
(function template)
compares two durations
(function template)
compares two time points
(function template)
compares the underlying std::type_info objects
(public member function of std::type_index) [edit]
compares two reverse_iterators for equality
(function template)
orders reverse_iterators
(function template)
compares two move_iterators
(function template)
compares two istream_iterators
(function template)
compares two istreambuf_iterators
(function template)
lexicographically compares the values in the two match result
(function template)
compares two regex_iterators
(function template)
compares two regex_token_iterators
(function template)
compares two thread::id objects
(function)
automatically generates comparison operators based on user-defined operator== and operator<
(function template) [edit]

See also

Operator precedence

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->b
a.b
a->*b
a.*b

a(...)
a, b
(type) a
? :

Special operators

static_cast converts one type to another compatible type
dynamic_cast converts virtual base class to derived class
const_cast converts type to compatible type with different cv qualifiers
reinterpret_cast converts type to incompatible type
new allocates memory
delete deallocates memory
sizeof queries the size of a type
sizeof... queries the size of a parameter 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)