Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions talk/concurrency/atomic.tex
Original file line number Diff line number Diff line change
Expand Up @@ -98,18 +98,17 @@
\begin{exampleblock}{}
\begin{cppcode*}{}
int a{0};
std::thread t1([&]{ std::atomic_ref<int> r{a}; r++;});
std::thread t2([&]{ std::atomic_ref{a}++; });
std::jthread t1([&]{ std::atomic_ref<int> r{a}; r++;});
std::jthread t2([&]{ std::atomic_ref{a}++; });
t1.join(); t2.join();
a += 2; // non-atomic (fine, threads joined before)
assert( a == 4 ); // Guaranteed to succeed
\end{cppcode*}
\end{exampleblock}
\begin{alertblock}{Don't mix concurrent atomic and non-atomic access}
\begin{cppcode*}{}
std::thread t3([&]{ std::atomic_ref{a}++; });
std::jthread t3([&]{ std::atomic_ref{a}++; });
a += 2; // data race
t3.join();
\end{cppcode*}
\end{alertblock}
\end{frame}
Expand Down
82 changes: 49 additions & 33 deletions talk/morelanguage/morestl.tex
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@
\end{frame}

\begin{frame}[fragile]
\frametitlecpp[17]{std::variant and the lambda visitor pattern}
\frametitlecpp[20]{std::variant and the lambda visitor pattern}
\begin{block}{Idea}
\begin{itemize}
\item use inheritance to group a set of lambdas
Expand All @@ -245,8 +245,7 @@
\begin{cppcode*}{}
template<typename... Ts> // covered in expert part
struct Overload : Ts ... { using Ts::operator()...; };
template<typename... Ts>
Overload(Ts...) -> Overload<Ts...>; // obsolete in C++20

int main(){
std::variant<int, float, std::string, char> v{ ... };
auto overloadSet = Overload {
Expand Down Expand Up @@ -312,8 +311,8 @@
\pause
\begin{block}{A new syntax}
\begin{cppcode*}{firstnumber=5}
for(auto it = begin(v); it != end(v); it++) {...}
for(auto i = begin(a); i != end(a); i++) {...}
for(auto it = std::begin(v); it != std::end(v); it++)
for(auto i = std::begin(a); i != std::end(a); i++)
\end{cppcode*}
\end{block}
\pause
Expand Down Expand Up @@ -357,39 +356,56 @@

\begin{frame}[fragile]
\frametitlecpp[11]{\texttt{std::tuple} \cpprefLink{https://en.cppreference.com/w/cpp/utility/tuple}}
\begin{exampleblock}{}
\begin{cppcode*}{}
#include <tuple>

std::tuple<int, float, bool> t{42, 3.14f, false};
auto t = std::make_tuple(42, 3.14f, false);
std::tuple t{42, 3.14f, false}; // C++17 CTAD

float& f = std::get<1>(t); // get 1. member
bool& b = std::get<bool>(t); // get bool member

using Tup = decltype(t);
constexpr auto s = std::tuple_size_v<Tup>; // 3
using E2Type = std::tuple_element<2, Tup>; // bool

auto t2 = std::tuple_cat(t, std::tuple{'A'}, t);
// <int, float, bool, char, int, float, bool>
bool& b2 = std::get<bool>(t2); // error
\end{cppcode*}
\end{exampleblock}
\begin{block}{A container for an arbitrary list of types}
\begin{itemize}
\item A tuple can contain any sequence of types
\item Use \texttt{make\_tuple} or initializer lists to construct
\item \texttt{std::get} retrieves elements
\item Various helpers: \texttt{tuple\_size}, \texttt{tuple\_element}, \texttt{tuple\_cat}
\end{itemize}
\end{block}
\vspace{-1em}
\begin{overprint}
\onslide<1>
\begin{exampleblock}{}
\begin{cppcode*}{}
#include <tuple>

std::tuple<int, float, bool> t{42, 3.14f, false};
auto t = std::make_tuple(42, 3.14f, false);
std::tuple t{42, 3.14f, false}; // C++17 CTAD

float f = std::get<1>(t); // get 1. member
bool b = std::get<bool>(t); // get bool member
\end{cppcode*}
\end{exampleblock}

\onslide<2>
\begin{exampleblock}{}
\begin{cppcode*}{}
std::tuple t{42, 3.14f, false}; // C++17 CTAD
using Tup = decltype(t);
constexpr auto s = std::tuple_size_v<Tup>; // 3
using E2Type = std::tuple_element<2, Tup>; // bool

auto t2 = std::tuple_cat(t, std::tuple{'A'}, t);
// <int, float, bool, char, int, float, bool>
bool& b2 = std::get<bool>(t2); // error
\end{cppcode*}
\end{exampleblock}
\end{overprint}
\end{frame}

\begin{frame}[fragile]
\frametitlecpp[11]{\texttt{std::tuple}}
\begin{exampleblock}{}
\begin{block}{References in tuples}
\begin{itemize}
\item Template argument deduction by default removes references
\item To put references into tuples, use reference wrappers
\end{itemize}
\end{block}
\begin{exampleblock}{Example: values and references}
\begin{cppcode*}{}
void f(std::tuple<int, float, bool> tuple) {
int a; float b; bool c;
std::tie(a, b, c) // tuple<int&, float&, bool&>
= tuple;
// Use structured bindings in C++17
}

int& i = ...;
std::tuple{i}; // tuple<int>
std::make_tuple(i); // tuple<int>
Expand Down
19 changes: 10 additions & 9 deletions talk/morelanguage/random.tex
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@
\begin{exampleblock}{Example}
\begin{cppcode}
#include <random>
std::random_device rd;
std::default_random_engine engine{rd()};

std::default_random_engine engine;
std::normal_distribution dist(5.0, 1.5); // µ, σ

double r = dist(engine);
\end{cppcode}
\end{exampleblock}
Expand Down Expand Up @@ -59,9 +60,9 @@
\begin{block}{\texttt{std::random\_device}}
\begin{itemize}
\item Provides \emph{non-deterministic} random numbers
\item Uses hardware provided entropy, if available
\item May become slow when called too often,\\e.g.\ when hardware entropy pool is exhausted
\item Use only to seed engine, if \emph{non-deterministic} numbers needed
\item Uses hardware-provided entropy, if available
\item May become slow when called too often
\item Can be used to start with random seed
\end{itemize}
\end{block}
\begin{exampleblock}{Non-deterministic engine seeding}
Expand All @@ -86,14 +87,14 @@
\end{block}
\begin{exampleblock}{Distributions sharing a non-deterministic engine}
\begin{cppcode*}{}
std::random_device rd;
std::default_random_engine engine{rd()};
std::ranlux48 eng{std::random_device{}()};

std::uniform_int_distribution<int> dist(2,7);//min,max
const int size = dist(engine); // gen. random number
const int size = dist(eng); // gen. random number
std::vector<int> v(size);
std::normal_distribution<double> norm(5.0, 1.5); //µ,σ
std::generate(begin(v), end(v),
[&]{ return norm(engine); });
[&]{ return norm(eng); });
\end{cppcode*}
\end{exampleblock}
\end{frame}
Expand Down
4 changes: 2 additions & 2 deletions talk/morelanguage/ranges.tex
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
\begin{block}{The range concept}
\begin{itemize}
\item A range is a sequence of items that you can iterate over
\item It must provide iterators to its beginning and end, obtainable via \cppinline{std::range::begin} and \cppinline{std::range::end}
\item It must provide iterators to its beginning and end, obtainable via \cppinline{std::ranges::begin} and \cppinline{std::ranges::end}
\item Range concepts are located in \cppinline{std::ranges} namespace
\item All STL containers are ranges
\end{itemize}
Expand All @@ -24,7 +24,7 @@
\begin{block}{The view concept}
\begin{itemize}
\item A \cppinline{view} is a non-owning object built from a range or another view after applying some range adaptor(s)
\item The time complexity to copy, move, assign is constant
\item Views are cheap to copy, move, and assign
\item Range adaptors can be applied/chained with \cppinline{|} and are lazy
\item They live in the \cppinline{std::views} namespace
\item They introduce easy functional programming to the STL
Expand Down
64 changes: 44 additions & 20 deletions talk/morelanguage/stl.tex
Original file line number Diff line number Diff line change
Expand Up @@ -254,41 +254,65 @@

\begin{frame}[fragile]
\frametitlecpp[11]{Functors / function objects}
\begin{block}{Example}
\begin{cppcode*}{}
struct Incrementer {
int m_inc;
Incrementer(int inc) : m_inc(inc) {}

int operator()(int value) const {
return value + m_inc;
}
};
std::vector<int> v{1, 2, 3};
const auto inc = 42;
std::transform(v.begin(), v.end(), v.begin(),
Incrementer{inc});
\begin{block}{Customise STL algorithms with functors}
\begin{itemize}
\item Many algorithms accept functors
\item Customise them by changing the functors
\end{itemize}
\end{block}
\vspace{-1.5em}
\begin{overprint}
\onslide<1>
\begin{block}{Example: sorting in reverse}
\begin{cppcode*}{}
#include <algorithm>
std::vector<int> numbers{1, 4, 2, 3};

// by default, uses "less" to compare elements
std::sort(numbers.begin(), numbers.end()); // 1 2 3 4

// change order by using a functor
std::sort(numbers.begin(), numbers.end(),
std::greater{}); // 4 3 2 1
\end{cppcode*}
\end{block}

\onslide<2>
\begin{block}{Example: a custom functor}
\begin{cppcode*}{}
std::vector<int> v{1, 2, 3};
struct Incrementer {
int m_inc;
Incrementer(int inc) : m_inc(inc) {}
int operator()(int value) const {
return value + m_inc;
}
};

std::transform(v.begin(), v.end(), v.begin(),
Incrementer{42});
\end{cppcode*}
\end{block}
\end{overprint}
\end{frame}

\begin{frame}[fragile]
\frametitlecpp[11]{Prefer lambdas over functors}
\frametitlecpp[14]{Prefer lambdas over functors}
\begin{exampleblock}{With lambdas}
\begin{cppcode*}{}
std::vector<int> v{1, 2, 3};
const auto inc = 42;
std::transform(begin(v), end(v), begin(v),
[inc](int value) {
std::transform(v.begin(), v.end(), v.begin(),
[inc = 42](int value) {
return value + inc;
});
\end{cppcode*}
\end{exampleblock}
\pause
\begin{goodpractice}[STL and lambdas]{Use STL algorithms with lambdas}
\begin{itemize}
\item Prefer lambdas over functors when using the STL
\item Avoid binders like \cppinline{std::bind2nd}, \cppinline{std::ptr_fun}, etc.
\item Use the standard functors where useful
\item Prefer lambdas over custom functors
\item No more need for binders like \cppinline{std::bind2nd}, \cppinline{std::ptr_fun}, etc.
\end{itemize}
\end{goodpractice}
\end{frame}
Expand Down
Loading