operator==,!=,<,<=,>,>=,<=>(std::tuple)
<tuple>
bool operator==( const std::tuple <TTypes...>& lhs,
(constexpr since C++14)
bool operator!=( const std::tuple <TTypes...>& lhs,
(constexpr since C++14)
(until C++20)
bool operator<( const std::tuple <TTypes...>& lhs,
(constexpr since C++14)
(until C++20)
bool operator<=( const std::tuple <TTypes...>& lhs,
(constexpr since C++14)
(until C++20)
bool operator>( const std::tuple <TTypes...>& lhs,
(constexpr since C++14)
(until C++20)
bool operator>=( const std::tuple <TTypes...>& lhs,
(constexpr since C++14)
(until C++20)
constexpr std::common_comparison_category_t <
synth-three-way-result<TTypes, Elems>...>
operator<=>( const std::tuple <TTypes...>& lhs,
constexpr bool operator==( const tuple<TTypes...>& lhs, const UTuple& rhs );
constexpr std::common_comparison_category_t <
synth-three-way-result<TTypes, /* Elems */>...>
[
0,
sizeof...(Types))
, the program is ill-formed.[
0,
sizeof...(Types))
, the behavior is undefined.
boolean-testable
for every i in [
0,
sizeof...(Types))
.
if (std::get<0>(lhs) < std::get<0>(rhs)) return true;
if (std::get<0>(rhs) < std::get<0>(lhs)) return false;
if (std::get<1>(lhs) < std::get<1>(rhs)) return true;
if (std::get<1>(rhs) < std::get<1>(lhs)) return false;
...
- For empty tuples, returns std::strong_ordering::equal.
- For non-empty tuples, the effect is equivalent to
if (auto c =
synth-three-way (std::get<0>(lhs), std::get<0>(rhs)); c != 0) return c;
if (auto c =
synth-three-way (std::get<1>(lhs), std::get<1>(rhs)); c != 0) return c;
...
return
synth-three-way (std::get<N - 1>(lhs), std::get<N - 1>(rhs));
tuple-like
object, and the number of elements of rhs is determined by std::tuple_size_v <UTuple> instead. This overload can only be found via argument-dependent lookup.tuple-like
object. /* Elems */ denotes the pack of types std::tuple_element_t <i, UTuple> for each i in [
0,
std::tuple_size_v <UTuple>)
in increasing order. This overload can only be found via argument-dependent lookup.All comparison operators are short-circuited; they do not access tuple elements beyond what is necessary to determine the result of the comparison.
The <
, <=
, >
, >=
, and !=
operators are synthesized from operator<=> and operator== respectively.
[edit] Parameters
[edit] Return value
[
0,
sizeof...(Types))
, otherwise false. For two empty tuples returns true.[edit] Notes
The relational operators are defined in terms of each element'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 an element type 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)Feature-test macro | Value | Std | Feature |
---|---|---|---|
__cpp_lib_constrained_equality |
202403L |
(C++26) | Constrained operator== for std::tuple |
[edit] Example
Because operator< is defined for tuples, containers of tuples can be sorted.
#include <algorithm> #include <iostream> #include <tuple> #include <vector> int main() { std::vector <std::tuple <int, std::string, float>> v { {2, "baz", -0.1}, {2, "bar", 3.14}, {1, "foo", 10.1}, {2, "baz", -1.1}, }; std::sort (v.begin(), v.end()); for (const auto& p: v) std::cout << "{ " << get<0>(p) << ", " << get<1>(p) << ", " << get<2>(p) << " }\n"; }
Output:
{ 1, foo, 10.1 } { 2, bar, 3.14 } { 2, baz, -1.1 } { 2, baz, -0.1 }
[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 2114 (P2167R3) |
C++11 | type preconditions for boolean operations were missing | added |
[edit] See also
pair
(function template) [edit]