|
55 | 55 | \end{cppcode*}
|
56 | 56 | \end{block}
|
57 | 57 | \begin{alertblock}{}
|
58 |
| - \begin{itemize} |
59 |
| - \item \mintinline{cpp}{const T&} won't work when passing something non const |
60 |
| - \end{itemize} |
| 58 | + and \mintinline{cpp}{const T&} won't work when passing something non const |
61 | 59 | \end{alertblock}
|
62 | 60 | \end{frame}
|
63 | 61 |
|
|
78 | 76 | \end{frame}
|
79 | 77 |
|
80 | 78 | \begin{frame}[fragile]
|
81 |
| - \frametitlecpp[11]{The new problem: scaling to n arguments} |
| 79 | + \frametitlecpp[11]{The new problem: scaling to more arguments} |
82 | 80 | \begin{block}{}
|
83 | 81 | \begin{cppcode*}{}
|
84 | 82 | template <typename T1, typename T2>
|
|
96 | 94 | \end{cppcode*}
|
97 | 95 | \end{block}{}
|
98 | 96 | \begin{alertblock}{Exploding complexity}
|
99 |
| - 3$^{n}$ complexity\\ |
100 |
| - you do not want to try n = 5... |
| 97 | + \begin{itemize} |
| 98 | + \item for $n$ arguments, 3$^{n}$ overloads |
| 99 | + \item you do not want to try n = 5... |
| 100 | + \end{itemize} |
101 | 101 | \end{alertblock}
|
102 | 102 | \end{frame}
|
103 | 103 |
|
|
187 | 187 | };
|
188 | 188 | \end{cppcode*}
|
189 | 189 | \end{alertblock}
|
| 190 | + \vspace{-1.2\baselineskip} |
| 191 | + \begin{overprint} |
| 192 | + \onslide<1> |
| 193 | + \begin{exampleblock}{Half-way correct version} |
| 194 | + \begin{cppcode*}{gobble=2} |
| 195 | + template <typename T> struct S { |
| 196 | + |
| 197 | + template <typename U> |
| 198 | + S(U&& t) { ... } // deducing context -> fwd. ref. |
| 199 | + template <typename U> |
| 200 | + void f(U&& t) // deducing context -> fwd. ref. |
| 201 | + // ... but now U can be a different type than T |
| 202 | + }; |
| 203 | + \end{cppcode*} |
| 204 | + \end{exampleblock} |
| 205 | + \onslide<2> |
190 | 206 | \begin{exampleblock}{Correct version}
|
191 | 207 | \begin{cppcode*}{gobble=2}
|
192 | 208 | template <typename T> struct S {
|
|
199 | 215 | };
|
200 | 216 | \end{cppcode*}
|
201 | 217 | \end{exampleblock}
|
| 218 | + \end{overprint} |
202 | 219 | \end{frame}
|
203 | 220 |
|
204 | 221 | \begin{frame}[fragile]
|
|
237 | 254 | \small
|
238 | 255 | \begin{cppcode*}{}
|
239 | 256 | template<typename T>
|
240 |
| - T&& forward(remove_reference_t<T>& t) noexcept { |
| 257 | + T&& forward(remove_reference_t<T>& t) noexcept { // 1. |
241 | 258 | return static_cast<T&&>(t);
|
242 | 259 | }
|
243 | 260 | template<typename T>
|
244 |
| - T&& forward(remove_reference_t<T>&& t) noexcept { |
| 261 | + T&& forward(remove_reference_t<T>&& t) noexcept { // 2. |
245 | 262 | return static_cast<T&&>(t);
|
246 | 263 | }
|
247 | 264 | \end{cppcode*}
|
248 | 265 | \end{block}
|
249 | 266 | \begin{block}{}
|
250 | 267 | \begin{itemize}
|
251 |
| - \item if \mintinline{cpp}{T} is \mintinline{cpp}{int}, it returns \mintinline{cpp}{int&&} |
252 |
| - \item if \mintinline{cpp}{T} is \mintinline{cpp}{int&}, it returns \mintinline{cpp}{int& &&}, i.e.\ \mintinline{cpp}{int&} |
253 |
| - \item if \mintinline{cpp}{T} is \mintinline{cpp}{int&&}, it returns \mintinline{cpp}{int&& &&}, i.e.\ \mintinline{cpp}{int&&} |
| 268 | + \item if \mintinline{cpp}{T} is \mintinline{cpp}{int}, selects 2., returns \mintinline{cpp}{int&&} |
| 269 | + \item if \mintinline{cpp}{T} is \mintinline{cpp}{int&}, selects 1., returns \mintinline{cpp}{int& &&}, i.e.\ \mintinline{cpp}{int&} |
| 270 | + \item if \mintinline{cpp}{T} is \mintinline{cpp}{int&&}, selects 2., returns \mintinline{cpp}{int&& &&}, i.e.\ \mintinline{cpp}{int&&} |
254 | 271 | \end{itemize}
|
255 | 272 | \end{block}
|
256 | 273 | \end{frame}
|
|
269 | 286 | \begin{itemize}
|
270 | 287 | \item if we pass an rvalue reference \mintinline{cpp}{U&&} to wrapper
|
271 | 288 | \begin{itemize}
|
272 |
| - \item arg will be of type \mintinline{cpp}{U&&} |
| 289 | + \item \mintinline{cpp}{T=U}, arg is of type \mintinline{cpp}{U&&} |
273 | 290 | \item func will be called with a \mintinline{cpp}{U&&}
|
274 | 291 | \end{itemize}
|
275 | 292 | \item if we pass an lvalue reference \mintinline{cpp}{U&} to wrapper
|
276 | 293 | \begin{itemize}
|
277 |
| - \item arg will be of type \mintinline{cpp}{U&} |
| 294 | + \item \mintinline{cpp}{T=U&}, arg is of type \mintinline{cpp}{U&} (reference collapsing) |
278 | 295 | \item func will be called with a \mintinline{cpp}{U&}
|
279 | 296 | \end{itemize}
|
280 | 297 | \item if we pass a plain \mintinline{cpp}{U} (rvalue) to wrapper
|
281 | 298 | \begin{itemize}
|
282 |
| - \item arg will be of type \mintinline{cpp}{U&&} (no copy in wrapper) |
| 299 | + \item \mintinline{cpp}{T=U}, arg is of type \mintinline{cpp}{U&&} (no copy in wrapper) |
283 | 300 | \item func will be called with a \mintinline{cpp}{U&&}
|
284 | 301 | \item if func takes a plain \mintinline{cpp}{U}, copy happens there, as expected
|
285 | 302 | \end{itemize}
|
|
0 commit comments