Skip to content

Commit

Permalink
Small improvements for more language chapter (#451)
Browse files Browse the repository at this point in the history
Those are inspired by my thoughts during the Friday essentials course lecture.
  • Loading branch information
bernhardmgruber committed May 8, 2023
1 parent 1018b25 commit 4dfec0b
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 79 deletions.
17 changes: 11 additions & 6 deletions talk/morelanguage/constness.tex
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,13 @@
// type of 'this' is 'Example const*'
data = 0; // Error: member function is const
}
void foo() { // ok, overload
data = 1; // ok, 'this' is 'Example*'
}
int data;
};
Example const e1; e1.foo(); // calls const foo
Example e2; e2.foo(); // calls non-const foo
\end{cppcode}
\end{frame}

Expand All @@ -76,16 +81,16 @@
\end{itemize}
\end{block}
\begin{cppcode}
void func(int & a);
void funcConst(int const & a);
void change(int & a);
void read(int const & a);

int a = 0;
int const b = 0;

func(a); // ok
func(b); // error
funcConst(a); // ok
funcConst(b); // ok
change(a); // ok
change(b); // error
read(a); // ok
read(b); // ok
\end{cppcode}
\end{frame}

Expand Down
129 changes: 66 additions & 63 deletions talk/morelanguage/lambda.tex
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,24 @@
\frametitlecpp[11]{Trailing function return type}
\begin{block}{An alternate way to specify a function's return type}
\begin{cppcode*}{linenos=false}
ReturnType func(Arg1 a, Arg2 b); // classic
auto func(Arg1 a, Arg2 b) -> ReturnType;
int f(float a); // classic
auto f(float a) -> int; // trailing
auto f(float a) { return 42; } // deduced, C++14
\end{cppcode*}
\end{block}
\pause
\begin{block}{Advantages}
\begin{itemize}
\item Allows to simplify inner type definition
\begin{cppcode*}{gobble=4}
class Class {
using ReturnType = int;
ReturnType func();
class Equation {
using ResultType = double;
ResultType evaluate();
}
Class::ReturnType Class::func() {...}
auto Class::func() -> ReturnType {...}
Equation::ResultType Equation::evaluate() {...}
auto Equation::evaluate() -> ResultType {...}
\end{cppcode*}
\item \cpp14: \cppinline{ReturnType} not required, compiler can deduce it
\item used by lambda expressions
\item Used by lambda expressions
\end{itemize}
\end{block}
\end{frame}
Expand All @@ -30,7 +30,7 @@
\begin{frame}[fragile]
\frametitlecpp[11]{Lambda expressions}
\begin{block}{Definition}
a lambda expression is a function with no name
A lambda expression is a function with no name
\end{block}
\pause
\begin{exampleblock}{Python example}
Expand Down Expand Up @@ -141,7 +141,10 @@
\end{alertblock}
\pause
\begin{block}{Explanation}
By default, variables are captured by value, and the lambda's \cppinline{operator()} is \cppinline{const}.
\begin{itemize}
\item By default, variables are captured by value
\item The lambda's \cppinline{operator()} is \cppinline{const}
\end{itemize}
\end{block}
\end{frame}

Expand All @@ -160,14 +163,64 @@
\begin{exampleblock}{Mixed case}
One can of course mix values and references
\begin{cppcode*}{firstnumber=5}
int sum = 0, offset = 1;
int sum = 0, off = 1;
int data[]{1,9,3,8,3,7,4,6,5};
auto f = [&sum, offset](int x) { sum += x+offset; };
auto f = [&sum, off](int x) { sum += x + off; };
for (int i : data) f(i);
\end{cppcode*}
\end{exampleblock}
\end{frame}

\begin{frame}[fragile]
\frametitlecpp[11]{Anatomy of a lambda}
\begin{block}{Lambdas are pure syntactic sugar - \cppinsightLink{https://cppinsights.io/s/67800da8}}
\begin{itemize}
\item They are replaced by a functor during compilation
\end{itemize}
\begin{columns}
\scriptsize
\begin{column}{.25\textwidth}
\begin{cppcode*}{gobble=6}
int sum = 0, off = 1;
auto l =
[&sum, off]



(int x) {
sum += x + off;
};


l(42);
\end{cppcode*}
\end{column}
\begin{column}{.45\textwidth}
\begin{cppcode*}{gobble=6, firstnumber=13}
int sum = 0, off = 1;
struct __lambda4 {
int& sum; int off;
__lambda4(int& s, int o)
: sum(s), off(o) {}

auto operator()(int x) const {
sum += x + off;
}
};
auto l = __lambda4{sum, off};
l(42);
\end{cppcode*}
\end{column}
\end{columns}
\end{block}
\begin{exampleblock}{Some nice consequence}
\begin{itemize}
\item Lambda expressions create ordinary objects
\item They can be copied, moved, or inherited from
\end{itemize}
\end{exampleblock}
\end{frame}

\begin{frame}[fragile]
\frametitlecpp[11]{Capture list}
\begin{block}{all by value}
Expand Down Expand Up @@ -219,56 +272,6 @@
Details in \href{https://www.nextptr.com/tutorial/ta1430524603/capture-this-in-lambda-expression-timeline-of-change}{this blog post}.
\end{frame}

\begin{frame}[fragile]
\frametitlecpp[11]{Anatomy of a lambda}
\begin{block}{Lambdas are pure syntactic sugar - \cppinsightLink{https://cppinsights.io/s/67800da8}}
\begin{itemize}
\item they are replaced by a functor during compilation
\end{itemize}
\begin{columns}
\scriptsize
\begin{column}{.25\textwidth}
\begin{cppcode*}{gobble=6}
int sum = 0, off = 1;
auto l =
[&sum, off]



(int x) {
sum += x + off;
};


l(42);
\end{cppcode*}
\end{column}
\begin{column}{.45\textwidth}
\begin{cppcode*}{gobble=6, firstnumber=13}
int sum = 0, off = 1;
struct __lambda4 {
int& sum;
int off;
__lambda4(int& s, int o)
: sum(s), off(o) {}
auto operator()(int x)const{
sum += x + off;
}
};
auto l = __lambda4{sum, off};
l(42);
\end{cppcode*}
\end{column}
\end{columns}
\end{block}
\begin{exampleblock}{Some nice consequence}
\begin{itemize}
\item lambda expressions create ordinary objects
\item they can in particular be inherited from!
\end{itemize}
\end{exampleblock}
\end{frame}

\begin{frame}[fragile]
\frametitlecpp[14]{Generic lambdas}
\begin{block}{Generic lambdas (aka.\ polymorphic lambdas)}
Expand Down
19 changes: 9 additions & 10 deletions talk/morelanguage/stl.tex
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,13 @@
#include <iterator>
#include <iostream>

std::vector<int> in{5, 3, 4}; // initializer list
std::vector<int> out(3); // constructor taking size
std::transform(in.begin(), in.end(), // range1
in.begin(), // start range2
out.begin(), // start result
std::multiplies{}); // function obj
std::copy(out.begin(), out.end(), // 25 9 16
std::ostream_iterator<int>{std::cout, " "});
std::vector<int> in{5, 3, 4}; // initializer list
std::vector<int> out(3); // constructor taking size
std::transform(in.begin(), in.end(), // input range
out.begin(), // start result
std::negate{}); // function obj
std::copy(out.begin(), out.end(), // -5 -3 -4
std::ostream_iterator<int>{std::cout, " "});
\end{cppcode*}
\end{exampleblockGB}
\end{frame}
Expand Down Expand Up @@ -190,7 +189,7 @@
\end{block}
\begin{exampleblockGB}{Iterator example}{https://godbolt.org/z/jv1qTo5xz}{Iterator example}
\begin{cppcode*}{}
std::vector<int> const v = {1, 2, 3, 4, 5, 6, 7, 8, 9};
std::vector<int> const v = {1,2,3,4,5,6,7,8,9};
auto const end = v.rend() - 3; // arithmetic
for (auto it = v.rbegin();
it != end; // compare positions
Expand Down Expand Up @@ -337,7 +336,7 @@
// Computes sin(x)/(x + DBL_MIN) for elements of a range.
std::vector<double> r(l.size());
std::transform(l.begin(), l.end(), r.begin(),
[](auto x) { return sin(x)/(x + DBL_MIN); });
[](auto x) { return std::sin(x)/(x + DBL_MIN); });

// reduce/fold (using addition)
const auto sum = std::reduce(v.begin(), v.end());
Expand Down
29 changes: 29 additions & 0 deletions talk/morelanguage/templates.tex
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,13 @@
struct Map {
void set(const KeyType &key, ValueType value);
ValueType get(const KeyType &key);
...
};

Map<std::string, int> m1;
Map<float> m2; // Map<float, float>
Map<> m3; // Map<int, int>
Map m4; // Map<int, int>, C++17
\end{cppcode*}
\end{frame}

Expand Down Expand Up @@ -151,6 +153,33 @@
\end{cppcode*}
\end{frame}

\begin{advanced}

\begin{frame}[fragile]
\frametitlecpp[98]{Nested templates}
\begin{exampleblockGB}{Nested templates}{https://godbolt.org/z/a9nPnK9jx}{Nested templates}
\small
\begin{cppcode*}{gobble=8}
template<typename KeyType=int, typename ValueType=KeyType>
struct Map {
template<typename OtherValueType>
void set(const KeyType &key, OtherValueType value) {
...
}
template<typename OtherKeyType>
ValueType get(const OtherKeyType &key);
};

template<typename KeyType, typename ValueType> //for class
template<typename OtherKeyType> //for member function
ValueType Map<KeyType, ValueType>::get
(const OtherKeyType &key) { ... }
\end{cppcode*}
\end{exampleblockGB}
\end{frame}

\end{advanced}

\begin{frame}[fragile]
\frametitle{Non-type template parameter \hfill \cpp98 / \cpp17 / \cpp20}
\begin{block}{template parameters can also be values}
Expand Down

0 comments on commit 4dfec0b

Please sign in to comment.