Namespaces
Variants
Actions

operator==, !=, <, <=, >, >=, <=>(std::optional)

From cppreference.com
< cpp‎ | utility‎ | optional
 
 
 
 
Defined in header <optional>
Compare two optional objects
template<class T, class U >
constexprbool operator==(const optional<T>& lhs, const optional<U>& rhs );
(1) (since C++17)
template<class T, class U >
constexprbool operator!=(const optional<T>& lhs, const optional<U>& rhs );
(2) (since C++17)
template<class T, class U >
constexprbool operator<(const optional<T>& lhs, const optional<U>& rhs );
(3) (since C++17)
template<class T, class U >
constexprbool operator<=(const optional<T>& lhs, const optional<U>& rhs );
(4) (since C++17)
template<class T, class U >
constexprbool operator>(const optional<T>& lhs, const optional<U>& rhs );
(5) (since C++17)
template<class T, class U >
constexprbool operator>=(const optional<T>& lhs, const optional<U>& rhs );
(6) (since C++17)
template<class T, std::three_way_comparable_with<T> U >

constexprstd::compare_three_way_result_t<T, U>

    operator<=>(const optional<T>& lhs, const optional<U>& rhs );
(7) (since C++20)
Compare an optional object with a nullopt
template<class T >
constexprbool operator==(const optional<T>& opt, std::nullopt_t)noexcept;
(8) (since C++17)
template<class T >
constexprbool operator==(std::nullopt_t, const optional<T>& opt )noexcept;
(9) (since C++17)
(until C++20)
template<class T >
constexprbool operator!=(const optional<T>& opt, std::nullopt_t)noexcept;
(10) (since C++17)
(until C++20)
template<class T >
constexprbool operator!=(std::nullopt_t, const optional<T>& opt )noexcept;
(11) (since C++17)
(until C++20)
template<class T >
constexprbool operator<(const optional<T>& opt, std::nullopt_t)noexcept;
(12) (since C++17)
(until C++20)
template<class T >
constexprbool operator<(std::nullopt_t, const optional<T>& opt )noexcept;
(13) (since C++17)
(until C++20)
template<class T >
constexprbool operator<=(const optional<T>& opt, std::nullopt_t)noexcept;
(14) (since C++17)
(until C++20)
template<class T >
constexprbool operator<=(std::nullopt_t, const optional<T>& opt )noexcept;
(15) (since C++17)
(until C++20)
template<class T >
constexprbool operator>(const optional<T>& opt, std::nullopt_t)noexcept;
(16) (since C++17)
(until C++20)
template<class T >
constexprbool operator>(std::nullopt_t, const optional<T>& opt )noexcept;
(17) (since C++17)
(until C++20)
template<class T >
constexprbool operator>=(const optional<T>& opt, std::nullopt_t)noexcept;
(18) (since C++17)
(until C++20)
template<class T >
constexprbool operator>=(std::nullopt_t, const optional<T>& opt )noexcept;
(19) (since C++17)
(until C++20)
template<class T >

constexprstd::strong_ordering

    operator<=>(const optional<T>& opt, std::nullopt_t)noexcept;
(20) (since C++20)
Compare an optional object with a value
template<class T, class U >
constexprbool operator==(const optional<T>& opt, const U& value );
(21) (since C++17)
template<class U, class T >
constexprbool operator==(const U& value, const optional<T>& opt );
(22) (since C++17)
template<class T, class U >
constexprbool operator!=(const optional<T>& opt, const U& value );
(23) (since C++17)
template<class U, class T >
constexprbool operator!=(const U& value, const optional<T>& opt );
(24) (since C++17)
template<class T, class U >
constexprbool operator<(const optional<T>& opt, const U& value );
(25) (since C++17)
template<class U, class T >
constexprbool operator<(const U& value, const optional<T>& opt );
(26) (since C++17)
template<class T, class U >
constexprbool operator<=(const optional<T>& opt, const U& value );
(27) (since C++17)
template<class U, class T >
constexprbool operator<=(const U& value, const optional<T>& opt );
(28) (since C++17)
template<class T, class U >
constexprbool operator>(const optional<T>& opt, const U& value );
(29) (since C++17)
template<class U, class T >
constexprbool operator>(const U& value, const optional<T>& opt );
(30) (since C++17)
template<class T, class U >
constexprbool operator>=(const optional<T>& opt, const U& value );
(31) (since C++17)
template<class U, class T >
constexprbool operator>=(const U& value, const optional<T>& opt );
(32) (since C++17)
template<class T, std::three_way_comparable_with<T> U >

constexprstd::compare_three_way_result_t<T, U>

    operator<=>(const optional<T>& opt, const U& value );
(33) (since C++20)

Performs comparison operations on optional objects.

1-7) Compares two optional objects, lhs and rhs. The contained values are compared (using the corresponding operator of T) only if both lhs and rhs contain values. Otherwise,
  • lhs is considered equal torhs if, and only if, both lhs and rhs do not contain a value.
  • lhs is considered less thanrhs if, and only if, rhs contains a value and lhs does not.
1-6) Let @ denote the corresponding comparison operator, for each of these functions:

If the corresponding expression *lhs @ *rhs is ill-formed or its result is not convertible to bool, the program is ill-formed.

(until C++26)

This overload participates in overload resolution only if the corresponding expression *lhs @ *rhs is well-formed and its result is convertible to bool.

(since C++26)
8-20) Compares opt with a nullopt. Equivalent to (1-6) when comparing to an optional that does not contain a value.

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

(since C++20)
21-33) Compares opt with a value. The values are compared (using the corresponding operator of T) only if opt contains a value. Otherwise, opt is considered less thanvalue.
21-32) Let @ denote the corresponding comparison operator, for each of these functions:

If the corresponding expression *opt @ value or value @ *opt (depending on the positions of the operands) is ill-formed or its result is not convertible to bool, the program is ill-formed.

(until C++26)

This overload participates in overload resolution only if all following conditions are satisfied:

  • U is not a specialization of std::optional.
  • The corresponding expression *opt @ value or value @ *opt (depending on the positions of the operands) is well-formed and its result is convertible to bool.
(since C++26)

Contents

[edit]Parameters

lhs, rhs, opt - an optional object to compare
value - value to compare to the contained value

[edit]Return value

1)lhs.has_value()!= rhs.has_value()?false:
    (lhs.has_value()==false?true:*lhs ==*rhs)
2)lhs.has_value()!= rhs.has_value()?true:
    (lhs.has_value()==false?false:*lhs !=*rhs)
3)!rhs ?false:(!lhs ?true:*lhs <*rhs)
4)!lhs ?true:(!rhs ?false:*lhs <=*rhs)
5)!lhs ?false:(!rhs ?true:*lhs >*rhs)
6)!rhs ?true:(!lhs ?false:*lhs >=*rhs)
7)lhs && rhs ?*lhs <=>*rhs : lhs.has_value()<=> rhs.has_value()
8,9)!opt
10,11)opt.has_value()
12)false
13)opt.has_value()
14)!opt
15)true
16)opt.has_value()
17)false
18)true
19)!opt
20)opt.has_value()<=>false
21)opt.has_value()?*opt == value :false
22)opt.has_value()? value ==*opt :false
23)opt.has_value()?*opt != value :true
24)opt.has_value()? value !=*opt :true
25)opt.has_value()?*opt < value  :true
26)opt.has_value()? value <*opt  :false
27)opt.has_value()?*opt <= value :true
28)opt.has_value()? value <=*opt :false
29)opt.has_value()?*opt > value  :false
30)opt.has_value()? value >*opt  :true
31)opt.has_value()?*opt >= value :false
32)opt.has_value()? value >=*opt :true
33)opt.has_value()?*opt <=> value : std::strong_ordering::less

[edit]Exceptions

1-7) May throw implementation-defined exceptions.
21-33) Throws when and what the comparison throws.

[edit]Notes

Feature-test macroValueStdFeature
__cpp_lib_constrained_equality202403L(C++26)constrained comparison operators for std::optional

[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 2945C++17 order of template parameters inconsistent for compare-with-T cases made consistent
close