\begin{lstlisting}[caption={typename als Hilfe zur Konfliktauflösung}, label=lst:typename_solves_conflicts]
\begin{lstlisting}[caption={\il{typename} als Hilfe zur Konfliktauflösung}, label=lst:typename_solves_conflicts]
template<typename T1> class X{
public:
// hier wüsste der Compiler nicht ob mem eine Member-Variable oder ein typedef ist. Dh. er weiß nicht ob das eine Multiplikation oder eine Referenz auf T::mem sein soll
\begin{lstlisting}[caption={Parameter an eine Funktion mappen, Parameter sind call by value, sofern nicht using ref(arg) oder cref(arg) (für const ref) verwendet wird}, label=lst:bind]
\begin{lstlisting}[caption={Parameter an eine Funktion mappen, Parameter sind call by value, sofern nicht \il{using ref(arg)} oder \il{cref(arg)} (für const ref) verwendet wird}, label=lst:bind]
// syntax: auto newCallable = bind(callable, arg_list)
\item Vorteil von Exception gegenüber Fehlercodes ist im Grunde die Trennung von Fehler-Auftreten und -Behandlung.
\item Im Destruktor sollten keine Exceptions geworfen werden, da sonst die Destruktoren, die diesen verwenden ihre exception-safety verlieren.
\item catch anything mit ``$\ldots$'': try{}catch(...){}
\item function-try-block: f(int i): g(i){}catch{}; Fängt auch den Aufruf der $g$-Funktion der Constructor-initialiser list ab.
\item catch anything mit \il{$\ldots$: try\{$\ldots$\}\ catch($\ldots$)\{\}}
\item function-try-block: \il{f(int i): g(i)\{\}\ catch\{\};} Fängt auch den Aufruf der \il{g}-Funktion der Constructor-initialiser list ab.
\end{itemize}
\inde{Exception Safe}{Programm verhält sich auch bei geworfenen Exceptions korrekt.}
...
...
@@ -14,7 +14,7 @@
\begin{itemize}
\item Diese Garantien können mittels Objekten gegeben werden. Im Constructor werden Ressourcen angefordert und im Destructor wieder freigegeben.
\item f(new T1, new T2); kann zu einem Memory-Leak führen: Speicher für beide Objekte wird angefordert und beim erzeugen von T1 fällt eine Exception.\\
\item\il{f(new T1, new T2);} kann zu einem Memory-Leak führen: Speicher für beide Objekte wird angefordert und beim erzeugen von \il{T1} fällt eine Exception.\\
Also stattdessen: \cref{lst:shared_pointer_exception}
\end{itemize}
...
...
@@ -38,18 +38,18 @@ template<typename T> T Stack<T>::pop(){
else{
// man verliert bei einem Fehler Elemente
T result = v[vused-1];
// ich weiß nicht genau wo hier eine Exception auftreten können sollte, aber ein underflow ist möglich, wodurch Objekte verloren werden können. Dies ist auch der allgemeine Gedanke hier: Fail nach dem decrease => Objekt nicht returnt, aber decreased.
// ich weiß nicht genau wo hier eine Exception auftreten können sollte, aber falls eine Exception nach dem decrease auftritt, so wird das Objekt nicht zurückgegeben, aber vused dennoch dekrementiert. => Objekt effektiv verloren
\begin{lstlisting}[caption={[noexcept]noexcept\\Das Versprechen keine Exception zu werfen wird gebrochen. Das gibt trotzdem höchstens eine Compile-Warnung. Zur Laufzeit terminiert dies das Programm}, label=lst:noexcept]
\begin{lstlisting}[caption={[\il{noexcept}]\il{noexcept}\\Das Versprechen keine Exception zu werfen wird gebrochen. Zur Übersetzungszeit resultiert dies höchstens in einer Compile-Warnung. Zur Laufzeit terminiert dies das Programm}, label=lst:noexcept]
\begin{lstlisting}[caption={[tuple, tie, make\_tuple, ignore]tuple, tie, make\_tuple, ignore\\first bis fourth enthalten die einzelnen Tupel-Komponenten, a und b das zweite bzw. vierte. Ganz zum Schluss enthält first die 2. Das erste tie ist nicht Notwendig verdeutlicht aber dessen Funktionalität.},label=lst:tuple_and_tie]
\begin{lstlisting}[caption={[\il{tuple, tie, make_tuple, ignore}]\il{tuple, tie, make_tuple, ignore}\\\il{first} bis \il{fourth} enthalten die einzelnen Tupel-Komponenten, \il{a} und \il{b} das zweite bzw. vierte. Ganz zum Schluss enthält \il{first} den Wert 2. Das erste \il{tie} ist nicht Notwendig verdeutlicht aber dessen Funktionalität.},label=lst:tuple_and_tie]
Eine nette Möglichkeit im 14er Standard zur Compile-Zeit die korrekte Funktion zu bestimmen sind restrictions und type traits.
Für Templates sollten nach Möglichkeit stets static\_asserts verwendet werden
Für Templates sollten nach Möglichkeit stets \il{static_assert}s verwendet werden
\begin{figure}[h!]
\begin{lstlisting}[caption={[lambda foo mit back\_inserter, partition\_copy, all\_of, none\_of, copy\_if]lambda foo mit back\_inserter, partition\_copy, all\_of, none\_of, copy\_if\\Kopiert alle ungeraden Elemente von myVec in allOdd und alle geraden in allEven.}, label=lst:lambda_foo_mit_back_inserter]
\begin{lstlisting}[caption={[lambda foo mit \il{back_inserter, partition_copy, all_of, none_of, copy_if}]lambda und \il{back_inserter, partition_copy, all_of, none_of, copy_if}\\Kopiert alle ungeraden Elemente von \il{myVec} in \il{allOdd} und alle geraden in \il{allEven}.}, label=lst:lambda_foo_mit_back_inserter]
list<int> allOdd;
deque<int> allEven;
vector<int> myVec = ...;
// odd ints to list allOdd and even ints to deque allEven
\begin{lstlisting}[caption={[Erweiterung2 zu \cref{lst:expression_functor,lst:extension_expression_functor}, run-time]Erweiterung2 zu \cref{lst:expression_functor,lst:extension_expression_functor}, run-time},label=lst:extension2_expression_functor]
// integration function (average of upper bound and lower bound sums)
\item push\_back konstante Zeit-Komplexität, wohingegen vector::insert lineare hat
\item\il{push_back} konstante Zeit-Komplexität, wohingegen \il{vector::insert} lineare hat
\item niemals mehrere Dinge in einem Statement allozieren (Exceptions)
\item ValueClass - sollte vorweisen: Copy-controll, keine Baseklasse sein und keine virtual functions, Verwendung auf dem Stack oder in anderen Klassen
\item BaseClass - virtual destructor, nonpublic copy-controll, virtual functions, Verwaltung dynamisch auf dem Heap. Verwendet mittels smart-Pointer in Form eines Objekts der abgeleiteten Klasse.
\item TraitsClass - Templates, die Type-Informationen mit sich führen, ausschließlich typedefs und static functions, keine veränderbaren Status oder virtuals, keine Instantiierung
\item PolicyClass - Fragmente in Form von Templates, keine Instantiierung
\item ExceptionClass - ungewöhnlicher Mix von Value und reference-Semantiken, thrown by value sollte von caught by reference aufgefangen werden, no-fail constructors, virtuelle Funktionen, erbt häufig virtuell von std::exception
\item\textit{ValueClass} - sollte vorweisen: Copy-controll, keine Baseklasse sein und keine virtual functions, Verwendung auf dem Stack oder in anderen Klassen
\item\textit{BaseClass} - virtual destructor, nonpublic copy-controll, virtual functions, Verwaltung dynamisch auf dem Heap. Verwendet mittels smart-Pointer in Form eines Objekts der abgeleiteten Klasse.
\item\textit{TraitsClass} - Templates, die Type-Informationen mit sich führen, ausschließlich typedefs und static functions, keine veränderbaren Status oder virtuals, keine Instantiierung
\item\textit{PolicyClass} - Fragmente in Form von Templates, keine Instantiierung
\item\textit{ExceptionClass} - ungewöhnlicher Mix von Value und reference-Semantiken, thrown by value sollte von caught by reference aufgefangen werden, no-fail constructors, virtuelle Funktionen, erbt häufig virtuell von std::exception
\item Composition sollte tight coupling (friend function, ...) vorgezogen werden, da dies bei Vererbungen besser ist
\item private Members sind ``nicht zugreifbar'', nicht jedoch ``unsichtbar'', dies kann mittels Pimpl idiom erreicht werden, was für Information-Hiding und Compiler-Grenzen sorgt. Versteckt hinter opaque pointer (optimalerweise smart pointer)\\
Kann buildtime verringern, vermeidet ambiguity, Beispiel \cref{lst:pimpl}
\item dynamic polymorphism - static type checking, dynamic binding, separate compilation
\item static polymorphism - static type checking, static binding, verschiedene Typen, compile-time evaluation $\rightarrow$ Optimierungen
\item\textit{dynamic polymorphism} - static type checking, dynamic binding, separate compilation
\item\textit{static polymorphism} - static type checking, static binding, verschiedene Typen, compile-time evaluation $\rightarrow$ Optimierungen
\item condition variable erlaubt Kommunikation mehrerer Prozesse mithilfe von Mutexen.
\item std::shared\_future ist wie std::future, aber zusätzlich können mehrere Threads auf den selben Zustand warten
\item Threads können sogar geswaped werden, warum auch immer man das tun wollte
\item aktueller Thread: std::this\_thread
\item\il{std::shared_future} ist wie \il{std::future}, aber zusätzlich können mehrere Threads auf den selben Zustand warten
\item Threads können sogar ausgetauscht(swap) werden, warum auch immer man das tun wollte
\item aktueller Thread: \il{std::this_thread}
\end{itemize}
\begin{figure}[h!]
\begin{lstlisting}[caption={[async n stuff]async - erlaubt keine Kommunikation über mehrere Prozesse}, label=lst:async]
\begin{lstlisting}[caption={[\il{async} n stuff]\il{async} - erlaubt keine Kommunikation über mehrere Prozesse}, label=lst:async]
int calculate(){ return 42; }
// startet Ausführung sofort
auto future = async(launch::async, calculate, <parameter>);
...
...
@@ -28,12 +28,12 @@ atomic<int> counter(0);
\begin{itemize}
\item lock\_guard: Verwendet mutex, lock im constructor, free im destructor. Ist schneller als unique\_lock
\item unique\_lock: genauso, aber kann auch später gelockt, unlocked und verschoben werden. Das ist notwendig wenn es sie condition variablen verwendet werden. Ist flexibler als lock\_guard
\item\il{lock_guard}: Verwendet \il{mutex, lock} im Konstruktor, \il{free} im Destruktor. Ist schneller als \il{unique_lock}
\item\il{unique_lock}: genauso, aber kann auch später gelockt, unlocked und verschoben werden. Das ist notwendig wenn condition variablen verwendet werden. Ist flexibler als \il{lock_guard}