Commit 3bc64fad authored by me's avatar me
Browse files

advPT tex source files

parents
summary.pdf
*.log
*.lol
*.out
*.lof
*.fls
*.tdo
*.fdb_latexmk
*.aux
.*.swp
*.lol
*.lot
*.toc
*.o
PDF = summary
RM = rm -f
LATEXMK = latexmk
LATEXMK_OPTS = -pdf
.PHONY: all clean
continuous: $(PDF).continuous
%.continuous: %.pdf
$(LATEXMK) $(LATEXMK_OPTS) $(@:%.continuous=%).tex
$(PDF): $(PDF).pdf
%.pdf: %.tex
$(LATEXMK) $(LATEXMK_OPTS) $< || (rm $(PDF).pdf ; exit 1)
all: $(PDF)
clean:
$(LATEXMK) -C
if [ -d "sections" ]; then cd sections && $(LATEXMK) -C; fi
$(RM) *.snm *.nav *.tdo *.lol
This repo contains the tex sources for my advPT-summary WS15/16
\section{Allgemeines}
\begin{itemize}
\item Weiterer Debugger: ddd
\item Profiler: gprof
\end{itemize}
Postfix-Operatoren erfordern das Anlegen einer Kopie, wenn der Operator von den entsprechenden C++-Klasse überladen wurde. Für die C-Datentypen sollte die Performanz identisch zu prefix sein.
Wenn der Operator aber inlined wird, dann sollte auch bei der postfix-Notation eine Optimierung seitens des Compilers ermöglicht werden.
\TODO{Auf den Folien steht es sei nur eine main-Funktion pro C++-Programm möglich. Das ist unpräzise. Aus Binary-Sicht ist das korrekt, aus Code-Sicht nicht, denn es können sich durchaus weitere main-Funktionen in anderen Namespaces verstecken.}
\begin{itemize}
\item std::cin nimmt auch eine Typprüfung vor.
\item Schlüsselwort ``explicit'' verhindert impliziten Aufruf bei Assignment. - Sinnvoll bei Copy-Constructor, wenn das Objekt sehr groß ist, um by-value-Funktionscalls zu vermeiden
\item Schlüsselwort ``auto'' als Typ lässt den Typ vom Compiler bei der Initialisierung bestimmen. Kann jedoch weder const, noch Referenzen repräsentieren.
\item In Bitfeldern sorgt ein 0-bitiger Eintrag für Alginment auf das nächste Byte
\item In Bitfeldern lassen sich mehrere Einträge zu einem zusammenfassen, z.B: int b:5, c:11 (Zugriff erfolgt über selben Eintrag)
\end{itemize}
\section{Lecture 7a}
\inde{virtual inheritance}{Mehrfachvererbung, wobei die Unterklasse eine einzige Kopie einer Basis-Klasse enthält, die innerhalb der Vererbungs-History mehrfach enthalten ist.
}
\indeItem{virtual base class}{
\begin{itemize}
\item Eine Basis-Klasse, die mittels ``virtual'' vererbt wurde. Diese ist lediglich einmal in dem Unterklassen-Objekt enthalten, selbst bei häufigerem Vorkommen als virtual Base.
\item Bei nicht-virtual-Vererbung initialisiert der Konstruktor womöglich lediglich die direkte Basis-Klasse.
\item Die Initialisierung von virtuellen Basis-Klassen erfolgt durch die niedrigste Unterklasse, die entsprechende Initialisierungen explizit vornehmen muss.
\end{itemize}
}
\indeItem{constructor order}{
\begin{itemize}
\item Aufruf der Konstruktoren erfolgt in der Reihenfolge der Derivation-List (nicht constructor-initialiser list).
\item Diese Initialisierung sollte explizit durch die constructor-initialiser-list erfolgen.
\item Konstruktoren virtueller Basisklassen werden vor den anderen aufgerufen
\end{itemize}
}
\subsection{Vorstellung des Projekts}
\begin{itemize}
\item Gebäude $\mapsto$ Production facilities
\begin{itemize}
\item Name
\item Kosten
\item Bereitgestellte Unterkunft
\item Bauzeit
\item Produzierbare Einheiten
\item Bedingte Gebäude, um dieses zu errichten
\item Mögliche Transformation in andere Gebäude
\end{itemize}
\item Einheiten $\mapsto$ Products
\begin{itemize}
\item Name
\item Kosten
\item Bereitgestellte/Benötigte Unterkunften
\item Bauzeit
\item In welchem Gebäudetypen werden sie erzeugt
\item Welche Gebäude werden zur Produktion benötigt
\item Mögliche Transformationen in andere Einheiten/Gebäude
\end{itemize}
\item Minerals and Vespin Gas $\mapsto$ Resources
\end{itemize}
\indeItem{Forward Simulation}{
Für jeden Schritt:
\begin{enumerate}
\item Update globale Ressourcen
\item Starte neue Produktion (sofern möglich), hänge diese in die Active-Action-List.\\
Suche Einheiten und weise diesen zu den freien Stellen in einer geeigneten production facility zu
\item Aktualisiere Active-Action-List. Produzierte Einheiten aus der Action-Liste entfernen. Entsprechende Veränderungen buchen.
\end{enumerate}
}
\indeItem{Optimisation of Build Lists}{
Geeignete Ansätze
\begin{itemize}
\item Exhaustive Search
\item Branch and Bound
\item Genetic Algorithm
\end{itemize}
}
\section{Lecture 8}
\begin{itemize}
\item class template vs function template
\item nontype parameter (value) vs type parameter
\item implizit mögliche Conversions:
\begin{itemize}
\item const conversion
\item array/function to pointer conversion
\end{itemize}
\item \TODO{Promotions werden nicht gemacht? Kann sein, sobald das Argument selbst templatisiert ist. sonst müsste es gehen}
\item Template Specialisation: Extra Fall für spezielle Typen
\end{itemize}
\begin{figure}[h!]
\begin{lstlisting}[caption={[Template Specialisation]Template Specialisation - Partial Specialisation ist nur bei Klassen erlaubt}, label=lst:template_specialisation]
template<typename T1, typename T2> void ff(){}
//anscheinend muss man hier tatsächlich alle explizit angeben
template <> void ff<int,int>(){}
//und deswegen geht das hier auch nicht, da partial specialisation nicht erlaubt ist
template <typename T1> void ff<T1,int>(){}
//bei Klassen hingegen geht das
template<typename T1, typename T2> class Y{};
template<typename T1> classY<T1, int>{};
\end{lstlisting}
\end{figure}
\begin{figure}[h!]
\begin{lstlisting}[caption={Template Specialisation kann sehr tricky sein}, label=lst:template_specialisation_crazy_example]
template<typename T>void f3(T t){}
template <typename T> void f3(T*){}
template <> void f3<int*>(int* a){}
int* ip = new int[2];
//ruft T* auf, weil die Specialisation eine Spezialisierung der ERSTEN Funktion ist und beim Finden des "best match" betrachtet der Compiler die beiden Generic-Funktionen, wovon die T* den besseren Match liefert.
f3(ip);
\end{lstlisting}
\end{figure}
\begin{figure}[h!]
\begin{lstlisting}[caption={Template Function in template class}, label=lst:template_function_off_template_class]
template<typename T1, typename T2>class Y{
public:
template<typename TT>void print(TT t);
};
//zwei template-Listen, deren Reihenfolge egal ist
template<typename T1, typename T2>template<typename TT>
void Y <T1, T2>::print(TT);
\end{lstlisting}
\end{figure}
\hspace*{-1cm}\begin{minipage}{1.1\linewidth}
\begin{lstlisting}[caption={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 weiss nicht ob das eine Multiplikation oder eine Referenz auf T::mem sein soll
//T::mem *p1;
//das hier sind die beiden Dinge, die für sich genommen funktionieren
static int const i = T::mem *p; //T::mem muss eine Variable sein
typename T::mem *p1; //T::mem muss ein type sein
};
\end{lstlisting}
\end{minipage}
\inde{Trailing return types \cref{lst:trailing_return_type}}{Zu Verwenden bei unbekanntem Return-Typen.}
\begin{figure}[h!]
\begin{lstlisting}[caption={[Trailing Return Type Beispiel]Trailing Return Type Beispiel\\Der Rückgabetyp steht hinter der Parameterliste}, label=lst:trailing_return_type]
template<typename It>
auto fcn(It beg, It end)->decltype(*beg){return *beg;}
\end{lstlisting}
\end{figure}
\inde{Forwarding \textit{std::forward\textless Type\textgreater(arg)} \cref{lst:forwarding_example}}{Ein Argument unverändert an die nächste Funktion weiterreichen. Dh const, non-const, lvalue, rvalue, ... bleibt bestehen
}
\begin{figure}[h!]
\begin{lstlisting}[caption={Forwarding Beispiel}, label=lst:forwarding_example]
//hier würde man sonst const und references verlieren
template<typename F, typename T1, typename T2>
void flip(F f, T1 &&t1, T2 &&t2){
f(std::forward<T2>(t2),std::forward<T1>(t1));
}
\end{lstlisting}
\end{figure}
\inde{variadic template \cref{lst:variadic_template_function}}{Template-Funktion/Klasse, die eine variable Anzahl Parameter entgegen nehmen kann.}
\begin{figure}[h!]
\begin{lstlisting}[caption={Variadic Template-Funktion. Erlaubt auch ziemlich coole Rekursionen}, label=lst:variadic_template_function]
template<typename T,typename ... Args>
void f(const T & t, const Args & rest);
template<typename T>
ostream &print(ostream &os, const T &t){
return os<<t;
}
template<typename T, typename... Args>
ostream &print(ostream &os, const T &t, const Args&... rest){
os<<t<<",";
return print(os,rest...);
}
\end{lstlisting}
\end{figure}
\inde{Member Template}{Kann nicht virtual sein. Entweder ein Klassen-Member oder ein Class-Template, das ein Funktions-Template ist. Man könnte es indirekt virtual machen, indem sie von einer Virtual-Funktion aus aufgerufen wird}
\section{Lecture 9}
\begin{itemize}
\item IO-Objekte können nicht assigned werden
\item condition state. Flag der Stream-Klassen, das angibt, ob der Stream korrumpiert ist oder valide
\begin{itemize}
\item fail: initialisation-fail, format-Error, Beispiel String to int, ermöglicht weitere Lese-Versuche mit anderen Parametern
\item bad: Böse Dinge sind passiert, Verwendung des Streams nicht mehr möglich
\item strm::iostate, strm::badbit, strm::failbit, strm::eofbit
\item s.good(), s.bad(), s.fail(), s.eof()
\item s.clear(), s.setstate(flag), s.rdstate()
\end{itemize}
\item stringstream scheint recht nützlich zu sein
\item Wenn ein Output-Stream an ein Input-Stream gebunden (stream.tie(\&stream2)) wird, dann wird dieser immer dann geflusht, wenn vom Input-Stream gelesen wird
\item Beim Program-Crash wird nicht geflusht
\item Deque (Double-ended queue) scheint wohl schneller zu sein, kann schnell vorne und hinten anfügen.\\
Es erfolgt beim Einfügen/Löschen keine Verschiebung von Elementen
\TODO{Schließt dies auch den Reallocation-Fall mit ein?}
\item List (Double-Linked List) ist prinzipiell relativ schnell bei Einfüge-/Löschoperationen\\
Invalidierung erfolgt nur für diese Iteratoren, die auf entfernte Elemente verwiesen. Bei Vektor werden alle Iteratoren, die auf ein beliebiges Element verweisen invalidiert (nicht jedoch bei swap).
\item push: Speichert eine Kopie in dem Container\\
emplace: Legt das Objekt erst im Container an
\end{itemize}
\begin{figure}[h!]
\begin{lstlisting}[caption={Stream-Flush}, label=lst:flush_of_streams]
//string, flush
cout << " " << flush;
//string, null, flush
cout << " " << ends;
//aktiviere unmittelbare Flush-Operationen nach input
cout << unitbuf;
\end{lstlisting}
\end{figure}
\section{Lecture 9a}
\begin{itemize}
\item Im Header stehende Template-Funktionen, wobei die Header in mehrere Source-Files includiert werden, werden unter Umständen mehrfach compiliert, nur um später weggeworfen zu werden.\\
Dies lässt sich vermeiden, indem die entsprechende Funktion mittels extern und template-Angaben in allen bis auf einer Datei bekannt gemacht wird.
\item Type traits (Type-Checking is\_\textless type\textgreater, z.B. is\_pointer) läuft zur Compile-Zeit durch
\item Man kann Class-Templates auch via verschachtelte-Class-Templates in die Class-Definition einer verwendenden Klasse angeben (vgl. \cref{lst:multiple_class_template})
\item Nette Fibonacci-Template-Metaprogramming (vgl. \cref{lst:template_meta_programming_loop_class})
\end{itemize}
\begin{figure}[h!]
\begin{lstlisting}[caption={[Verschachtelte Class-Templates]Verschachtelte Class-Templates\\fibonacci ist also das innere Template. Die innere Template-Class erspart es uns jedesmal Fibonacci\textless unsigned long\textgreater zu schreiben.}, label=lst:multiple_class_template]
template<template<unsigned long> class T>
class Loop{ void function(); };
template<unsigned long N> class Fibonacci<N>{...};
Loop<Fibonacci>::function();
\end{lstlisting}
\end{figure}
\begin{figure}[h!]
\begin{lstlisting}[caption={Template-Meta-Programming Fibonacci mit Klassen}, label=lst:template_meta_programming_loop_class]
template<unsigned long beg, unsigned long end, template<unsigned long>class T>
class Loop{
public:
template<typename Container>
static void run(Container &v){
//value sind die Fibonacci-Zahlen, diese werden woanders berechnet (s.u.)
v.push_back(T<beg>::value);
Loop<beg+1,end,T>::run(v);
}
};
//template specialisation, Abbruchbedingung
template<unsigned long end, template<unsigned long>class T>
class Loop<end,end, T>{
public:
template<typename Container>
static void run(Container &v){}
};
template<unsigned long N>
class Fibonacci{
public:
static const int value = Fibonacci<N-2>::value+Fibonacci<N-1>::value;
//alternativ
enum{value2 = Fibonacci<N-2>::value2 + Fibonacci<N-1>::value2};
};
//specialisation 0
template<>
class Fibonacci<0u>{
public:
static const int value = 0;
enum{value2 = 0};
};
//specialisation 1
template<>
class Fibonacci<1u>{
public:
static const int value = 1;
enum{value2 = 1};
};
\end{lstlisting}
\end{figure}
\section{Lecture 10}
\begin{figure}[h!]
\begin{lstlisting}[caption={[Duplikate entfernen]Duplikate entfernen\\Dank des Sortiervorgangs entfernt dies tatsächlich sämtliche Duplikate. Ohne diesen würden lediglich die aufeinanderfolgenden Duplikate entfernt.}, label=lst:remove_duplicates]
sort(words.begin(),words.end());
//Überschreiben von aufeinanderfolgenden Duplikaten mit dem nächsten von den Duplikaten unterschiedlichen Wert. Das Ende bleibt unverändert, somit auch die Größe.
vector<string>::iterator endunique = unique(words.begin(),words.end());
//das Ende (die bereits vorgezogenen Werte) löschen
words.erase(endunique, words.end());
\end{lstlisting}
\end{figure}
\begin{figure}[h!]
\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]
//syntax: auto newCallable = bind(callable,arg_list)
#include <functional> //std::ref
using namespace std::placeholders; //_1
string s;
vector<string>words;
while(cin >> s)
words.push_back(s);
for_each(words.begin(),words.end(),
bind(print,ref(cout),_1, ' '));
//for_each funktioniert auch mit lambda-Funktionen (s.u. Algorithmen-Syntax)
for_each(words.begin(),words.end(),
[](string s){cout << s << " ";}));
ostream &print(ostream &os, const string &s, char c){
return os << s << c;
}
\end{lstlisting}
\end{figure}
\begin{figure}[h!]
\begin{lstlisting}[caption={[Auslesen eines Inputfile(Stream)s via Iterator und Ausgabe]Auslesen eines Inputfile(Stream)s via Iterator, Ausgabe erfolgt Wortweise, jeweils in einer neuen Zeile.}, label=lst:ifstream_iterator]
ifstream is("data/outFile1");
istream_iterator<string> in (is), eof;
for_each(in, eof, bind(print, ref(cout), _1, '\n'));
\end{lstlisting}
\end{figure}
\begin{figure}[h!]
\begin{lstlisting}[caption={Insert iterator}, label=lst:insert_iterator]
vector<int> vec;
//insert elements at the tail
auto it = back_inserter(vec);
//equivalent to vec.push_back(42)
*it = 42;
//front_inserter verwendet push_front
\end{lstlisting}
\end{figure}
\indeItem{Iterators}{
\begin{itemize}
\item Iterators sollten allgemein nicht dereferenziert werden, da sie auf nicht-existierende Elemente verweisen können.
\item reverse iterator - bewegt sich von hinten durch die Folge und invertiert entsprechend die Bedeutung von ++ und \textminus\textminus
\item Iterator-Hierarchie
\begin{enumerate}
\item input iterator - kann Elemente nur lesen, nicht schreiben
\item output iterator - kann Elemente nur schreiben, nicht lesen
\item forward iterator - kann Elemente lesen und schreiben, aber ``\textminus\textminus'' ist nicht unterstützt
\item bidirectional iterator - forward iterator mit Support für ``\textminus\textminus''
\item random-access iterator - bidirectional iterator mit der Fähigkeit Iterator-Werte mit relationalen Operatoren zu vergleichen und arithmetische Operationen auf dem Iterator auszuführen. Entsprechend wird random access unterstützt.
\end{enumerate}
\item Algorithmen-Syntax
\begin{itemize}
\item alg(beg, end, params);
\item alg(beg, end, dest, params);
\item alg(beg, end, beg2 params); (zwei Iteratoren)
\item alg(beg, end, beg2, end2, params); (zwei Iteratoren)
\end{itemize}
\end{itemize}
}
\begin{figure}[h!]
\begin{lstlisting}[caption={Algorithmen transform}, label=lst:algorithms]
vector<int> vi;
int i;
while(cin >> i)
vi.push_back(i);
//läuft durch den ersten Iterator und ersetzt im selben Index des zweiten Iterator den Wert mit dem absoluten Wert
transform(vi.begin(), vi.end(), vi.begin(),
[](int i){return i < 0 ? -i : i;});
\end{lstlisting}
\end{figure}
\begin{figure}[h!]
\begin{lstlisting}[caption={Vector-Dinge: fill, fill\_n, accumulate, copy}, label=lst:vector_stuff]
vector<int> vec(10); //initialises to 0 per default
fill(vec.begin(), vec.end(), 1); //set all values to 1
//c{begin,end} returnt einen const_iterator, dieser kann die Werte des Containers nicht verändern, auch nicht wenn dieser non-const ist.
//aufsummieren aller Werte, wobei die Summe mit 0 beginnt
int sum = accumulate(vec.cbegin(), vec.cend(), 0);
//falls vec ein vector<double> ist, dann müsste der Startwert angepasst werden:
int sum2 = accumulate(vec.cbegin(), vec.cend(), 0.);
//erzeuge 10 Elemente am Ende des Vektors mit dem Wert 42
fill_n(back_inserter(vec), 10, 42);
//accumulate funktioniert auch auf Strings
vector<string> v;
...
string concat = accumulate(v.cbegin(), v.cend(), string(""));
//Initialisierung mittels istream_iterator
istream_iterator<int> in_iter(cin), eof;
vector<int> vec(in_iter, eof);
//Ausgabe mittels ostream_itertor
ostream_iterator<int> out_iter(cout, " " );
copy(vec.begin(), vec.end(), out_iter);
//alternativ
for(auto e: vec)
*out_iter++ = e;
\end{lstlisting}
\end{figure}
\begin{itemize}
\item inserter(\textless List\textgreater, \textless List-Insert-Start-Position\textgreater) - Keine Ahnung weshalb hier beides benötigt wird
\end{itemize}
\ \\[0,4cm]
\begin{itemize}
\item associative container - Object-Collection mit effizientem key-lookup (nach Key sortiert)\\
set, map, multiset, multimap
\begin{itemize}
\item multiset, multimap
\begin{itemize}
\item lower\_bound(k) - Iterator zu dem ersten Element, dessen Key-Wert mindestens $k$ ist. Falls also $k$ nicht enthalten ist, dann verweist dies auf das erste Element mit einen Größeren Key als $k$
\item upper\_bound(k) - Erste Element mit einem Key größer $k$
\item equal\_range(k) - Ein Iterator-Paar das lower\_bound(k), upper\_bound(k) entspricht
\end{itemize}
\end{itemize}
\item unordered container - Verwenden Hashing, und keine Ordnung der Schlüsselwerte\\
unordered\_map, unordered\_set, unordered\_multimap, unordered\_multiset
\end{itemize}
\begin{figure}[h!]
\begin{lstlisting}[caption={Container Dinge}, label=lst:container_stuff]
//count the number of times each word occurs in the input
//map from string to size_t
map<string, size_t> word_count;
string word;
while(cin >> word)
++word_count[word];
for(const auto &w : word_count)
cout << w.first << " occurs " << w.second << " times" << endl;
\end{lstlisting}
\end{figure}
\section{Lecture 11}
\begin{itemize}
\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.
\end{itemize}
\inde{Exception Safe}{Programm verhält sich auch bei geworfenen Exceptions korrekt.}
\inde{Basic guarantee}{Sämtliche Objekte können nach einer Exception entweder weiter korrekt verwendet oder zerstört werden.}
\inde{Strong guarantee}{commit/rollback Semantik. Keine Seiteneffekte, z.B. werden Iteratoren nicht invalidiert.}
\inde{Nofail guarantee}{Es kann keine Exception auftreten}
\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.\\
Also stattdessen: \cref{lst:shared_pointer_exception}
\end{itemize}
\begin{figure}[h!]
\begin{lstlisting}[caption={[Exception safe Code mit shared pointers]Exception safe Code mit shared pointers.\\Es ist wichtig, dass die Objekte NICHT in dem Aufruf angelegt werden.}, label=lst:shared_pointer_exception]
void f(shared_ptr<T1>, shared_ptr<T2>);
shared_ptr<T1> t1(new T1);
shared_ptr<T2> t2(new T2);
f(t1,t2);
\end{lstlisting}
\end{figure}
\begin{figure}[h!]
\begin{lstlisting}[caption={Exception safe durch Trennung der Instruktionen}, label=lst:exception_stuff]
//nicht exception safe
template<typename T> T Stack<T>::pop(){
if(!vused)
throw std::runtime_error("pop from empty stack");
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.
--vused;
return result;
}
}
//Also in einzelne Operationen spalten
template<typename T> T&Stack<T>::top(){
if(!vused)
throw std::runtime_error("empty stack");
return v[vused -1];
}
template<typename T> void Stack<T>::pop(){
if(!vused)
throw std::runime_error("pop from empty stack");
else
--vused;
}
\end{lstlisting}
\end{figure}
\begin{figure}[h!]
\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]
void f()noexcept{
throw exception();
}
\end{lstlisting}
\end{figure}
\section{Lecture 12}
\begin{figure}[h!]
\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]
int a, b;
int first, second, third, fourth;
auto tup3 = tie(first, second, third, fourth) = std::make_tuple(1001, 1002, 1003, 1004);
tie(std::ignore, a, std::ignore, b) = tup3;
//mutation des Elements first
get<0>(tup3) = 2;
\end{lstlisting}
\end{figure}
\begin{figure}[h!]
\begin{lstlisting}[caption={Regex},label=lst:regex]
emailDescription = ".......";
//regex for email address
string regExprStr(R"((\w+(\.|_)?\w*)@(\w+\.\w+)+))");
//regex holder
regex rgx(regExprStr);
//search result holder
smatch smatch;
//search, dies matcht auf das LETZTE Vorkommen des Regex, dh. vorherige Treffer werden überschrieben
if(regex_search(emailDescription, smatch, rgx)){
cout << "whole adress: " << smatch[0] << "\n";
cout << "local part (before @): " << smatch[1] << "\n";
cout << "domain name (after @): " << smatch[3] << "\n";
cout << "string before the match: " << smatch.prefix() << "\n";
cout << "string after the match: " << smatch.postfix() << "\n";
}
//um alle Matches zu bekommen:
sregex_token_iterator itBegin(emailDescription.begin(), emailDescription.end(), regExprStr);
const sregex_token_iterator itEnd;
while(itBegin != itEnd)
cout << *itBegin++ << endl;
\end{lstlisting}
\end{figure}
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\_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]
list<int> allOdd;
deque<int> allEven;
vector<int> myVec = ...;
//odd ints to list allOdd and even ints to deque allEven
partition_copy(myVec.begin(), myVec.end(),
back_inserter(allOdd), back_inserter(allEven),
[](int i){return i % 2;});
//weitere funktionen
//true falls alle Elemente ungerade
bool b = all_of(myVec.begin(), myVec.end(),
[](int i){return i%2;});
//true falls alle Elemente gerade
bool c = none_of(myVec.begin(),myVec.end(),
[](int i){return i%2;});
//kopiert alle ungeraden Elemente nach cout