General topics | ||||||||||||||||
Flow control | ||||||||||||||||
Conditional execution statements | ||||||||||||||||
Iteration statements (loops) | ||||||||||||||||
Jump statements | ||||||||||||||||
Functions | ||||||||||||||||
Function declaration | ||||||||||||||||
Lambda function expression | ||||||||||||||||
inline specifier | ||||||||||||||||
Dynamic exception specifications(until C++17*) | ||||||||||||||||
noexcept specifier(C++11) | ||||||||||||||||
Exceptions | ||||||||||||||||
Namespaces | ||||||||||||||||
Types | ||||||||||||||||
Specifiers | ||||||||||||||||
| ||||||||||||||||
Storage duration specifiers | ||||||||||||||||
Initialization | ||||||||||||||||
Expressions | ||||||||||||||||
Alternative representations | ||||||||||||||||
Literals | ||||||||||||||||
Boolean -Integer -Floating-point | ||||||||||||||||
Character -String -nullptr(C++11) | ||||||||||||||||
User-defined(C++11) | ||||||||||||||||
Utilities | ||||||||||||||||
Attributes(C++11) | ||||||||||||||||
Types | ||||||||||||||||
typedef declaration | ||||||||||||||||
Type alias declaration(C++11) | ||||||||||||||||
Casts | ||||||||||||||||
Memory allocation | ||||||||||||||||
Classes | ||||||||||||||||
Class-specific function properties | ||||||||||||||||
| ||||||||||||||||
Special member functions | ||||||||||||||||
Templates | ||||||||||||||||
Miscellaneous | ||||||||||||||||
General | ||||
Literals | ||||
Operators | ||||
Conversions | ||||
Compares the arguments.
Operator name | Syntax | Overloadable | Prototype examples (forclass 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 | R T::operator<=>(const U& b)const;[1] | R operator<=>(const T& a,const U& b);[1] |
|
Contents |
The two-way comparison operator expressions have the form
lhs< rhs | (1) | ||||||||
lhs> rhs | (2) | ||||||||
lhs<= rhs | (3) | ||||||||
lhs>= rhs | (4) | ||||||||
lhs== rhs | (5) | ||||||||
lhs!= rhs | (6) | ||||||||
For built-in two-way comparison operators,lvalue-to-rvalue conversions,array-to-pointer conversions(until C++26) andfunction-to-pointer conversions are applied tolhs andrhs .
The comparison is deprecated if bothlhs andrhs 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, thearray-to-pointer conversion is performed on the other operand. For built-in equality operators, if one of the operands is a pointer or anull 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 abool prvalue.
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(unsignedchar)< sizeof(int),"Cannot compare signed and smaller unsigned properly");int a=-1;int b=1;unsignedint c=1;unsignedchar 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 ? falseComparing signed and unsigned: -1 == 1 ? false -1 < 1 ? false -1 > 1 ? trueComparing signed and smaller unsigned: -1 == 1 ? false -1 < 1 ? true -1 > 1 ? false
The converted operands of equality operators==
and!=
can also have the typestd::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 ofp andq | Value yielded by | |
---|---|---|
p== q | p!= q | |
equal | true | false |
unequal | false | true |
unspecified | unspecifiedbool value |
If at least one of convertedlhs andrhs is a pointer,pointer conversions,function pointer conversions(since C++17) andqualification conversions are performed on both converted operands to bring them to theircomposite pointer type. The two pointers of the composite pointer type are compared as follows:
If at least one of convertedlhs andrhs is a pointer to member,pointer-to-member conversions,function pointer conversions(since C++17) andqualification conversions are performed on both converted operands to bring them to theircomposite pointer type. The two pointers to members of the composite pointer type are compared as follows:
C1
and the other refers to a member of a different classC2
, where neither is a base class of the other, the result is unspecified.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);// falsebool y=(pb== pl);// true
Two operands of typestd::nullptr_t or one operand of typestd::nullptr_t and the other a null pointer constant compare equal. | (since C++11) |
The converted operands of relational operators>
,<
,>=
and<=
can also have pointer type.
Built-in pointer relational comparison on unequal pointersp andq 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 ofp andq | 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 | unspecifiedbool value |
If convertedlhs andrhs are both pointers,pointer conversions,function pointer conversions(since C++17) andqualification conversions are performed on both converted operands to bring them to theircomposite pointer type. The two pointers of the composite pointer type are compared as follows:
There exists animplementation-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:
| (since C++14) |
| (since C++20) |
Inoverload resolution against user-defined operators, for every pair of promoted arithmetic typesL
andR
, 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 typeP
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 typeMP
that is a pointer to member object or pointer to member function orstd::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? falsep1 < p2? truePointers to members of a class:p3 == p4? falsep3 < p4? truePointers to members of a union:p5 == (void*)p6? truep5 < (void*)p6? false
Three-way comparisonThe three-way comparison operator expressions have the form
The expression returns an object such that
If one of the operands is of typebool 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 If at least one of the operands is a pointer to object or pointer to member,array-to-pointer conversions,pointer conversions andqualification conversions are applied to both operands to bring them to theircomposite pointer type. For converted pointer operandsp andq,p<=> q returns a prvalue of typestd::strong_ordering:
Otherwise, the program is ill-formed. OverloadsInoverload resolution against user-defined operators, for pointer or enumeration type
Where Run this code Output: -0 and 0 are equal | (since C++20) |
Because comparison operators group left-to-right, the expressiona< b< c is parsed(a< b)< c, and nota<(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 foruser-defined operator< isstrict weak ordering. In particular, this is required by the standard algorithms and containers that work withCompare types:std::sort,std::max_element,std::map, etc.
Thecomparison result of pointers to different non-static data members of the same class implies that non-static data members in each of the threemember 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 providestrict 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 ofstd::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 asstd::set orstd::map.
For the types that are bothEqualityComparable andLessThanComparable, the C++ standard library makes a distinction betweenequality, which is the value of the expressiona== b andequivalence, which is the value of the expression!(a< b)&&!(b< a).
Comparison between pointers and null pointer constants was removed by the resolution ofCWG issue 583 included inN3624:
void f(char* p){if(p>0){/*...*/}// Error with N3624, compiled before N3624if(p> nullptr){/*...*/}// Error with N3624, compiled before N3624} int main(){}
Three-way comparison can be automatically generated for class types, seedefault comparisons.
If both of the operands are arrays, three-way comparison is ill-formed.
unsignedint i=1;auto r=-1< i;// existing pitfall: returns ‘false’auto r2=-1<=> i;// Error: narrowing conversion required
Feature-test macro | Value | Std | Feature |
---|---|---|---|
__cpp_impl_three_way_comparison | 201907L | (C++20) | Three-way comparison (compiler support) |
__cpp_lib_three_way_comparison | 201907L | (C++20) | Three-way comparison (library support); adding three-way comparison to the library |
Comparison operators are overloaded for many classes in the standard library.
(removed in C++20) | checks whether the objects refer to the same type (public member function of std::type_info )[edit] |
(removed in C++20)(removed in C++20)(C++20) | compares twoerror_code s(function)[edit] |
(removed in C++20)(removed in C++20)(C++20) | compareserror_condition s anderror_code s(function)[edit] |
(removed in C++20)(removed in C++20)(removed in C++20)(removed in C++20)(removed in C++20)(C++20) | lexicographically compares the values in thepair (function template)[edit] |
(removed in C++20)(removed in C++20)(removed in C++20)(removed in C++20)(removed in C++20)(C++20) | lexicographically compares the values in the tuple (function template)[edit] |
(removed in C++20) | compares the contents (public member function of std::bitset<N> )[edit] |
(removed in C++20) | compares two allocator instances (public member function of std::allocator<T> )[edit] |
(removed in C++20)(C++20) | compares to anotherunique_ptr or withnullptr(function template)[edit] |
(removed in C++20)(removed in C++20)(removed in C++20)(removed in C++20)(removed in C++20)(C++20) | compares with anothershared_ptr or withnullptr(function template)[edit] |
(removed in C++20) | compares astd::function withnullptr (function template)[edit] |
(C++11)(C++11)(removed in C++20)(C++11)(C++11)(C++11)(C++11)(C++20) | compares two durations (function template)[edit] |
(C++11)(C++11)(removed in C++20)(C++11)(C++11)(C++11)(C++11)(C++20) | compares two time points (function template)[edit] |
(removed in C++20) | compares twoscoped_allocator_adaptor objects(function template)[edit] |
(removed in C++20)(C++20) | compares the underlyingstd::type_index objects (public member function of std::type_index )[edit] |
(removed in C++20)(removed in C++20)(removed in C++20)(removed in C++20)(removed in C++20)(C++20) | lexicographically compares two strings (function template)[edit] |
(removed in C++20) | equality comparison between locale objects (public member function of std::locale )[edit] |
(C++11)(C++11)(removed in C++20)(C++11)(removed in C++20)(C++11)(removed in C++20)(C++11)(removed in C++20)(C++11)(removed in C++20)(C++20) | lexicographically compares the values of twoarray s(function template)[edit] |
(removed in C++20)(removed in C++20)(removed in C++20)(removed in C++20)(removed in C++20)(C++20) | lexicographically compares the values of twodeque s(function template)[edit] |
(C++11)(C++11)(removed in C++20)(C++11)(removed in C++20)(C++11)(removed in C++20)(C++11)(removed in C++20)(C++11)(removed in C++20)(C++20) | lexicographically compares the values of twoforward_list s(function template)[edit] |
(removed in C++20)(removed in C++20)(removed in C++20)(removed in C++20)(removed in C++20)(C++20) | lexicographically compares the values of twolist s(function template)[edit] |
(removed in C++20)(removed in C++20)(removed in C++20)(removed in C++20)(removed in C++20)(C++20) | lexicographically compares the values of twovector s(function template)[edit] |
(removed in C++20)(removed in C++20)(removed in C++20)(removed in C++20)(removed in C++20)(C++20) | lexicographically compares the values of twomap s(function template)[edit] |
(removed in C++20)(removed in C++20)(removed in C++20)(removed in C++20)(removed in C++20)(C++20) | lexicographically compares the values of twomultimap s(function template)[edit] |
(removed in C++20)(removed in C++20)(removed in C++20)(removed in C++20)(removed in C++20)(C++20) | lexicographically compares the values of twoset s(function template)[edit] |
(removed in C++20)(removed in C++20)(removed in C++20)(removed in C++20)(removed in C++20)(C++20) | lexicographically compares the values of twomultiset s(function template)[edit] |
(C++11)(C++11)(removed in C++20) | compares the values in the unordered_map (function template)[edit] |
(C++11)(C++11)(removed in C++20) | compares the values in the unordered_multimap (function template)[edit] |
(C++11)(C++11)(removed in C++20) | compares the values in the unordered_set (function template)[edit] |
(C++11)(C++11)(removed in C++20) | compares the values in the unordered_multiset (function template)[edit] |
lexicographically compares the values of twoqueue s(function template)[edit] | |
lexicographically compares the values of twostack s(function template)[edit] | |
compares the underlying iterators (function template)[edit] | |
(C++11)(C++11)(removed in C++20)(C++11)(C++11)(C++11)(C++11)(C++20) | compares the underlying iterators (function template)[edit] |
(removed in C++20) | compares twoistream_iterator s(function template)[edit] |
(removed in C++20) | compares twoistreambuf_iterator s(function template)[edit] |
(removed in C++20) | compares two complex numbers or a complex and a scalar (function template)[edit] |
compares two valarrays or a valarray with a value (function template)[edit] | |
(C++11)(C++11)(removed in C++20) | compares the internal states of two pseudo-random number engines (function)[edit] |
(C++11)(C++11)(removed in C++20) | compares two distribution objects (function)[edit] |
(removed in C++20)(removed in C++20)(removed in C++20)(removed in C++20)(removed in C++20)(C++20) | compares asub_match with anothersub_match , a string, or a character(function template)[edit] |
(removed in C++20) | lexicographically compares the values in the two match result (function template)[edit] |
(removed in C++20) | compares tworegex_iterator s(public member function of std::regex_iterator<BidirIt,CharT,Traits> )[edit] |
(removed in C++20) | compares tworegex_token_iterator s(public member function of std::regex_token_iterator<BidirIt,CharT,Traits> )[edit] |
(removed in C++20)(removed in C++20)(removed in C++20)(removed in C++20)(removed in C++20)(C++20) | compares twothread::id objects(function)[edit] |
The namespacestd::rel_ops provides generic operators!=,>,<=, and>=:
Defined in header <utility> | |
Defined in namespace std::rel_ops | |
(deprecated in C++20) | automatically generates comparison operators based on user-definedoperator== andoperator< (function template)[edit] |
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. whether1<2 yieldstrue orfalse) were unspecified | specification added |
CWG 879 | C++98 | pointers to function types and pointers tovoid 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<= ) ofpointers tovoid and function pointers were removed byN3624 | 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 |
Common operators | ||||||
---|---|---|---|---|---|---|
assignment | increment decrement | arithmetic | logical | comparison | member access | other |
a= b | ++a | +a | !a | a== b | a[...] | function call a(...) |
comma a, b | ||||||
conditional a? b: c | ||||||
Special operators | ||||||
static_cast converts one type to another related type |
C documentation forComparison operators |