\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
//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
//und deswegen geht das hier auch nicht, da partial specialisation nicht erlaubt ist
//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.
//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.
\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;
//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
//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}
...
...
@@ -77,7 +77,7 @@ auto fcn(It beg, It end)->decltype(*beg){return *beg;}
\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.
//Überschreiben von aufeinanderfolgenden Duplikaten mit dem nächsten von den Duplikaten unterschiedlichen Wert. Das Ende bleibt unverändert, somit auch die Größe.
\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
//syntax: auto newCallable = bind(callable,arg_list)
#include <functional> //std::ref
using namespace std::placeholders; //_1
string s;
vector<string>words;
...
...
@@ -23,7 +23,7 @@ while(cin >> 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 funktioniert auch mit lambda-Funktionen (s.u. Algorithmen-Syntax)
\begin{lstlisting}[caption={Exception safe durch Trennung der Instruktionen}, label=lst:exception_stuff]
//nicht exception safe
//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
//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 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.
\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)
//integration function (average of upper bound and lower bound sums)
//funktioniert, da Referenz zu einem rvalue (geht nicht mit nur einem '&'), entspricht nun einer move operation
// funktioniert, da Referenz zu einem rvalue (geht nicht mit nur einem '&', da 10 ein rvalue und kein lvalue ist und ri3 daher vom Typ rvalue reference und nicht vom Typ lvalue reference sein muss)
// rvalue references werden häufig für move Semantik verwendet
int &&ri3 = 10;
int i = 42; int &&rr = i*42;
//const funktioniert, da intern zu int konvertiert
//const funktioniert, da intern zu int konvertiert
\begin{lstlisting}[caption={Floatberechnung Compile vs. Runtime}, label=lst:float_calculations_compile_vs_runtime]
char array[1+int(1+0.2-0.1-0.1)];//compiletime
char array[1+int(1+0.2-0.1-0.1)];//compiletime
int size = 1+int(1+0.2-0.1-0.1);// maybe at runtime
sizeof(array)==size;// muss nicht wahr sein
\end{lstlisting}
...
...
@@ -14,7 +14,7 @@ sizeof(array)==size;// muss nicht wahr sein
\begin{figure}[h!]
\begin{lstlisting}[caption={Cooles Operator-Überladen mit constexpr},label=lst:overloaded_operators_with_constexpr]
\begin{lstlisting}[caption={Operator-Überladen mit constexpr},label=lst:overloaded_operators_with_constexpr]
struct A{
constexpr A(int i) : val(i){}
constexpr operator int() const {return val;}
...
...
@@ -24,8 +24,8 @@ private:
template<int> struct X{};
constexpr A a = 42; //constructor
X<a> x; //verwendet int-operator für das template
constexpr A a = 42; //constructor
X<a> x; //verwendet int-operator für das template
\end{lstlisting}
\end{figure}
...
...
@@ -35,10 +35,10 @@ X<a> x; //verwendet int-operator für das template
constexpr int factorial(int n){return n <= 1 ? 1: (n*factorial(n-1));}
template<int n>
struct {constN(){//do stuff
struct {constN(){//do stuff
}};
//kann trotzdem zur Laufzeit ausgewertet werden, wenn Ziel als volatile deklariert
//kann trotzdem zur Laufzeit ausgewertet werden, wenn Ziel als volatile deklariert
constN<factorial(4)> result;
\end{lstlisting}
\end{figure}
...
...
@@ -47,22 +47,24 @@ constN<factorial(4)> result;
\begin{figure}[h!]
\begin{lstlisting}[caption={Sicherstellung der Größe von dem Eingabe-String $a$ gleich $N$}, label=lst:ensure_sizeof_input_string]
\begin{lstlisting}[caption={Sicherstellung der Größe von dem Eingabe-String \il{a} gleich \il{N}}, label=lst:ensure_sizeof_input_string]
func(const char (&a)[N])
\end{lstlisting}
\end{figure}
\inde{allocator}{Interessante Klasse, die via Template: allocator\textless type\textgreater name; die Speicherverwaltung von Elementen vom Typ type vornehmen kann, ohne deren Konstruktor aufrufen zu müssen\\
name.allocate(amount) //alloziert für amount Elemente vom Typ type den Speicher\\
name.construct(index) // Ruft den Konstruktor für das index-te Element auf\\
name.destroy(index)
\inde{allocator}{Interessante Klasse, die via Template: \il{allocator <type> name;} die Speicherverwaltung von Elementen vom Typ type vornehmen kann, ohne deren Konstruktor aufrufen zu müssen\\
\il{name.allocate(amount) //alloziert für amount Elemente vom Typ type den Speicher}\\
\il{name.construct(index) // Ruft den Konstruktor für das index-te Element auf}\\
\il{name.destroy(index)}
}
\begin{figure}[h!]
\begin{lstlisting}[caption={Kopieren und befüllen},label=lst:copy_and_fill]
uninitialized_copy(start, end, destination) //kopiert die Elemente des Bereichs start-end nach destination
uninitialized_fill_n(destination, amount, element) // füllt amount viele Slots von destination mit element auf
// kopiert die Elemente des Bereichs start-end nach destination
uninitialized_copy(start, end, destination)
// füllt amount viele Slots von destination mit element auf
\begin{lstlisting}[caption={[Placement new]Placement new\\Das Objekt wird in dem übergebenen Speicherbereich erzeugt, es wird also kein neuer Speicherplatz angefordert. Und es erfolgt auch kein unnötiger Kopiervorgang.},label=lst:placement_new]
allocator<string> alloc;
string *sp = alloc.allocate(2);
new (sp) string(begin, end) //Erzeugt den String in dem raw-Feld mit replacement
// Erzeugt den String in dem raw-Feld mit replacement
new (sp) string(begin, end)
\end{lstlisting}
\end{figure}
Bei smart pointer (löschen sich selbst sobald keine Referenz mehr darauf existiert) wird auf ``use count'' zurückgegriffen. Das wird automatisch bei new und delete modifiziert.
Bei smart pointer (löschen sich selbst sobald keine Referenz mehr darauf existiert) wird auf ``use count'' zurückgegriffen. Dieser wird automatisch bei \il{new} und \il{delete} modifiziert.