|
4 | 4 | \frametitle{The burden of comparison operators}
|
5 | 5 | \begin{block}{Motivation}
|
6 | 6 | \begin{itemize}
|
7 |
| - \item One often needs \mintinline{cpp}{operator<} for a home-made class |
| 7 | + \item One often needs \mintinline{cpp}{operator<} for a user-defined class |
8 | 8 | \begin{itemize}
|
9 | 9 | \item e.g.\ when sorting a \mintinline{cpp}{std::vector}
|
10 | 10 | \item e.g.\ when using it as a key for \mintinline{cpp}{std::set} or \mintinline{cpp}{std::map}
|
|
14 | 14 | \item \mintinline{cpp}{operator>}, \mintinline{cpp}{operator>=}, \mintinline{cpp}{operator<=}, ...
|
15 | 15 | \item often implemented reusing e.g.\ \mintinline{cpp}{operator<} and \mintinline{cpp}{operator==}
|
16 | 16 | \end{itemize}
|
17 |
| - \item All these should be defined as free functions, optionally friends |
| 17 | + \item Should be defined as hidden friend functions |
18 | 18 | \item Much boilerplate code to write. Too much...
|
19 | 19 | \end{itemize}
|
20 | 20 | \end{block}
|
|
38 | 38 | \begin{itemize}
|
39 | 39 | \item similar to \mintinline{cpp}{std::strcmp}
|
40 | 40 | \end{itemize}
|
41 |
| - \item greater, lower or equal to \mintinline{cpp}{0} means respectively \emph{lower than}, \emph{greater than} and \emph{equivalent to} |
| 41 | + \item lower, greater, or equal to \mintinline{cpp}{0} means respectively \emph{lower than}, \emph{greater than} and \emph{equivalent to} |
42 | 42 | \item It is provided by default for all built-in types and many types in the standard library
|
43 | 43 | \end{itemize}
|
44 | 44 | \end{exampleblock}
|
|
50 | 50 | \begin{cppcode*}{}
|
51 | 51 | template <typename T>
|
52 | 52 | void three_way_compare( T lhs, T rhs ) {
|
53 |
| - auto res = ( lhs <=> rhs ); |
54 |
| - std::cout << "(" << lhs << "<=>" << rhs << ") : " |
| 53 | + auto res = lhs <=> rhs; |
| 54 | + std::cout << lhs << "<=>" << rhs << ": " |
55 | 55 | << (res<0) << (res==0) << (res>0)
|
56 |
| - << std::endl; |
| 56 | + << '\n'; |
57 | 57 | }
|
58 | 58 | int main() {
|
59 |
| - three_way_compare(1, 2); // (1<=>2): 100 |
60 |
| - three_way_compare(2, 2); // (2<=>2): 010 |
61 |
| - three_way_compare(2, 1); // (2<=>1): 001 |
| 59 | + three_way_compare(1, 2); // 1<=>2: 100 |
| 60 | + three_way_compare(2, 2); // 2<=>2: 010 |
| 61 | + three_way_compare(2, 1); // 2<=>1: 001 |
62 | 62 | }
|
63 | 63 | \end{cppcode*}
|
64 | 64 | \end{exampleblock}
|
65 | 65 | \end{frame}
|
66 | 66 |
|
67 | 67 | \begin{frame}[fragile]
|
68 | 68 | \frametitlecpp[20]{Different kinds of ordering}
|
69 |
| - \begin{block}{About the return type of \texttt{operator<=>}} |
| 69 | + \begin{block}{The return type of \texttt{operator<=>}} |
70 | 70 | \begin{itemize}
|
71 | 71 | \item for integers \mintinline{cpp}{operator<=>} returns \mintinline{cpp}{std::strong_ordering}
|
72 |
| - \item \mintinline{cpp}{partial_ordering} and \mintinline{cpp}{weak_ordering} also exist |
| 72 | + \item \mintinline{cpp}{weak_ordering} and \mintinline{cpp}{partial_ordering} also exist |
73 | 73 | \end{itemize}
|
74 | 74 | \end{block}
|
75 | 75 | \begin{exampleblock}{3 types of ordering}
|
76 | 76 | \begin{description}[partial]
|
77 | 77 | \item[strong] exactly one test among \mintinline{cpp}{<0}, \mintinline{cpp}{==0}, and \mintinline{cpp}{>0} will return \mintinline{cpp}{true}
|
78 |
| - \item[partial] like strong but all tests may return \mintinline{cpp}{false} |
79 |
| - \begin{itemize} |
80 |
| - \item e.g.\ compare a floating point to \mintinline{cpp}{NaN} |
81 |
| - \end{itemize} |
82 | 78 | \item[weak] like strong but two \emph{equivalent} values may differ
|
83 | 79 | \begin{itemize}
|
84 | 80 | \item they are however \emph{equivalent} for ranking
|
85 | 81 | \item e.g.\ rational numbers $2/3$ and $4/6$
|
86 | 82 | \end{itemize}
|
| 83 | + \item[partial] like weak but some values are incomparable |
| 84 | + \begin{itemize} |
| 85 | + \item for some values all tests may return \mintinline{cpp}{false} |
| 86 | + \item e.g.\ compare a floating point to \mintinline{cpp}{NaN} |
| 87 | + \end{itemize} |
87 | 88 | \end{description}
|
88 | 89 | \end{exampleblock}
|
89 | 90 | \end{frame}
|
|
104 | 105 | }
|
105 | 106 | };
|
106 | 107 | int main() {
|
107 |
| - // floats use partial_ordering |
108 |
| - three_way_compare(+0., -0.); // (0<=>-0) : 010 |
109 |
| - three_way_compare(0./1., 1./0.); // (0<=>inf) : 100 |
110 |
| - three_way_compare(0., 0./0.); // (0<=>-nan) : 000 |
111 |
| -
|
112 | 108 | // Ratio uses weak_ordering
|
113 |
| - three_way_compare(Ratio{1, 2}, Ratio{2, 3}); // (1/2<=>2/3) : 100 |
114 |
| - three_way_compare(Ratio{2, 3}, Ratio{4, 6}); // (2/3<=>4/6) : 010 |
115 |
| - three_way_compare(Ratio{2, 3}, Ratio{1, 2}); // (2/3<=>1/2) : 001 |
| 109 | + three_way_compare(Ratio{1, 2}, Ratio{2, 3}); // 1/2<=>2/3 : 100 |
| 110 | + three_way_compare(Ratio{2, 3}, Ratio{4, 6}); // 2/3<=>4/6 : 010 |
| 111 | + three_way_compare(Ratio{2, 3}, Ratio{1, 2}); // 2/3<=>1/2 : 001 |
| 112 | +
|
| 113 | + // floats use partial_ordering |
| 114 | + three_way_compare(+0., -0.); // 0<=>-0 : 010 |
| 115 | + three_way_compare(0., 1./0.); // 0<=>inf : 100 |
| 116 | + three_way_compare(0., 0./0.); // 0<=>-nan : 000 |
116 | 117 | }
|
117 | 118 | \end{cppcode*}
|
118 | 119 | \end{exampleblock}
|
|
122 | 123 | \frametitlecpp[20]{Compiler-generated comparison operators}
|
123 | 124 | \begin{block}{For a given user-defined class}
|
124 | 125 | \begin{itemize}
|
125 |
| - \item defining \mintinline{cpp}{operator<=>} allows the compiler to use it when encountering any other comparison operators |
126 |
| - \item of course, one can replace the default implementations |
| 126 | + \item defining \mintinline{cpp}{operator<=>} allows the compiler to use it when encountering the comparison operators \mintinline{cpp}{<}, \mintinline{cpp}{<=}, \mintinline{cpp}{>} and \mintinline{cpp}{>=} |
| 127 | + \item of course, one can still provide a custom implementation |
127 | 128 | \item the compiler will \emph{NOT} add a default implementation for \mintinline{cpp}{operator==} and \mintinline{cpp}{operator!=}
|
128 | 129 | \begin{itemize}
|
129 | 130 | \item as those operators mean \textbf{equal}, rather than \textbf{equivalent}
|
130 |
| - \item if \mintinline{cpp}{operator<=>} does not provide a strong order, it is advised not to define \mintinline{cpp}{operator==} yourself |
| 131 | + \item if \mintinline{cpp}{operator<=>} does not provide a strong order, it is advised not to define \mintinline{cpp}{operator==} |
131 | 132 | \end{itemize}
|
132 | 133 | \end{itemize}
|
133 | 134 | \end{block}
|
|
153 | 154 | \frametitlecpp[20]{\texttt{operator<=>} summary}
|
154 | 155 | \begin{block}{Summary}
|
155 | 156 | \begin{itemize}
|
156 |
| - \item Defining \mintinline{cpp}{operator<=>} allows you to use \mintinline{cpp}{operator<}, \mintinline{cpp}{operator>},\mintinline{cpp}{operator<=}, and \mintinline{cpp}{operator>=} for free |
| 157 | + \item Defining \mintinline{cpp}{operator<=>} allows you to use \mintinline{cpp}{operator<}, \mintinline{cpp}{operator>}, \mintinline{cpp}{operator<=}, and \mintinline{cpp}{operator>=} for free |
157 | 158 | \item The standard library defines a few kinds of orderings
|
158 | 159 | \begin{itemize}
|
159 | 160 | \item strong, weak and partial
|
160 | 161 | \end{itemize}
|
161 |
| - \item If \mintinline{cpp}{operator<=>} does not define a strong order, avoid defining \mintinline{cpp}{operator==}. |
| 162 | + \item If \mintinline{cpp}{operator<=>} does not define a strong ordering, avoid defining \mintinline{cpp}{operator==} |
162 | 163 | \end{itemize}
|
163 | 164 | \end{block}
|
164 | 165 | \end{frame}
|
0 commit comments