Commit c8544743 authored by me's avatar me
Browse files

clarified some statements and improved visual decisions

parent 3bc64fad
......@@ -13,12 +13,12 @@
\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
// 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
template <typename T1> void ff<T1,int>(){}
//bei Klassen hingegen geht das
// bei Klassen hingegen geht das
template<typename T1, typename T2> class Y{};
template<typename T1> classY<T1, int>{};
\end{lstlisting}
......@@ -31,7 +31,7 @@ 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.
// 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}
......@@ -44,7 +44,7 @@ template<typename T1, typename T2>class Y{
public:
template<typename TT>void print(TT t);
};
//zwei template-Listen, deren Reihenfolge egal ist
// zwei template-Listen, deren Reihenfolge egal ist
template<typename T1, typename T2>template<typename TT>
void Y <T1, T2>::print(TT);
\end{lstlisting}
......@@ -55,12 +55,12 @@ void Y <T1, T2>::print(TT);
\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{figure}[h!]
\begin{lstlisting}[caption={Forwarding Beispiel}, label=lst:forwarding_example]
//hier würde man sonst const und references verlieren
// 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));
......
......@@ -24,13 +24,13 @@ emplace: Legt das Objekt erst im Container an
\begin{figure}[h!]
\begin{lstlisting}[caption={Stream-Flush}, label=lst:flush_of_streams]
//string, flush
// string, flush
cout << " " << flush;
//string, null, flush
// string, null, flush
cout << " " << ends;
//aktiviere unmittelbare Flush-Operationen nach input
// aktiviere unmittelbare Flush-Operationen nach input
cout << unitbuf;
\end{lstlisting}
\end{figure}
......@@ -27,13 +27,13 @@ class Loop{
public:
template<typename Container>
static void run(Container &v){
//value sind die Fibonacci-Zahlen, diese werden woanders berechnet (s.u.)
// 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 specialisation, Abbruchbedingung
template<unsigned long end, template<unsigned long>class T>
class Loop<end,end, T>{
public:
......@@ -46,18 +46,18 @@ template<unsigned long N>
class Fibonacci{
public:
static const int value = Fibonacci<N-2>::value+Fibonacci<N-1>::value;
//alternativ
// alternativ
enum{value2 = Fibonacci<N-2>::value2 + Fibonacci<N-1>::value2};
};
//specialisation 0
// specialisation 0
template<>
class Fibonacci<0u>{
public:
static const int value = 0;
enum{value2 = 0};
};
//specialisation 1
// specialisation 1
template<>
class Fibonacci<1u>{
public:
......
......@@ -2,9 +2,9 @@
\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.
// Ü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
// das Ende (die bereits vorgezogenen Werte) löschen
words.erase(endunique, words.end());
\end{lstlisting}
\end{figure}
......@@ -12,9 +12,9 @@ words.erase(endunique, words.end());
\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
// 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)
for_each(words.begin(),words.end(),
[](string s){cout << s << " ";}));
......@@ -47,11 +47,11 @@ for_each(in, eof, bind(print, ref(cout), _1, '\n'));
\begin{figure}[h!]
\begin{lstlisting}[caption={Insert iterator}, label=lst:insert_iterator]
vector<int> vec;
//insert elements at the tail
// insert elements at the tail
auto it = back_inserter(vec);
//equivalent to vec.push_back(42)
// equivalent to vec.push_back(42)
*it = 42;
//front_inserter verwendet push_front
// front_inserter verwendet push_front
\end{lstlisting}
\end{figure}
......@@ -85,7 +85,7 @@ 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
// 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}
......@@ -94,34 +94,34 @@ transform(vi.begin(), vi.end(), vi.begin(),
\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
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
// 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:
// 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
// erzeuge 10 Elemente am Ende des Vektors mit dem Wert 42
fill_n(back_inserter(vec), 10, 42);
//accumulate funktioniert auch auf Strings
// accumulate funktioniert auch auf Strings
vector<string> v;
...
string concat = accumulate(v.cbegin(), v.cend(), string(""));
//Initialisierung mittels istream_iterator
// Initialisierung mittels istream_iterator
istream_iterator<int> in_iter(cin), eof;
vector<int> vec(in_iter, eof);
//Ausgabe mittels ostream_itertor
// Ausgabe mittels ostream_itertor
ostream_iterator<int> out_iter(cout, " " );
copy(vec.begin(), vec.end(), out_iter);
//alternativ
// alternativ
for(auto e: vec)
*out_iter++ = e;
\end{lstlisting}
......@@ -152,8 +152,8 @@ unordered\_map, unordered\_set, unordered\_multimap, unordered\_multiset
\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
// 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)
......
......@@ -31,21 +31,21 @@ f(t1,t2);
\begin{figure}[h!]
\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.
--vused;
return result;
}
}
//Also in einzelne Operationen spalten
// Also in einzelne Operationen spalten
template<typename T> T&Stack<T>::top(){
if(!vused)
throw std::runtime_error("empty stack");
......
......@@ -5,7 +5,7 @@ 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
// mutation des Elements first
get<0>(tup3) = 2;
\end{lstlisting}
\end{figure}
......@@ -13,13 +13,13 @@ get<0>(tup3) = 2;
\begin{figure}[h!]
\begin{lstlisting}[caption={Regex},label=lst:regex]
emailDescription = ".......";
//regex for email address
// regex for email address
string regExprStr(R"((\w+(\.|_)?\w*)@(\w+\.\w+)+))");
//regex holder
// regex holder
regex rgx(regExprStr);
//search result holder
// search result holder
smatch smatch;
//search, dies matcht auf das LETZTE Vorkommen des Regex, dh. vorherige Treffer werden überschrieben
// 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";
......@@ -28,7 +28,7 @@ if(regex_search(emailDescription, smatch, rgx)){
cout << "string after the match: " << smatch.postfix() << "\n";
}
//um alle Matches zu bekommen:
// um alle Matches zu bekommen:
sregex_token_iterator itBegin(emailDescription.begin(), emailDescription.end(), regExprStr);
const sregex_token_iterator itEnd;
while(itBegin != itEnd)
......@@ -47,19 +47,19 @@ Für Templates sollten nach Möglichkeit stets static\_assert s verwendet werden
list<int> allOdd;
deque<int> allEven;
vector<int> myVec = ...;
//odd ints to list allOdd and even ints to deque allEven
// 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
// 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
// true falls alle Elemente gerade
bool c = none_of(myVec.begin(),myVec.end(),
[](int i){return i%2;});
//kopiert alle ungeraden Elemente nach cout
// kopiert alle ungeraden Elemente nach cout
copy_if(myVec.begin(), myVec.end(),
ostream_iterator<int>(cout, " "), [](int i) {return i%2;});
// })})})}) <- fix vim-hightlighting
......
......@@ -6,13 +6,13 @@
\begin{figure}[h!]
\begin{lstlisting}[caption={[Expression Functor, run-time]Expression Functor, run-time},label=lst:expression_functor]
//expression abstract base class -> dynamic polymorphism
// expression abstract base class -> dynamic polymorphism
struct Expression{
virtual double operator() (double) = 0;
virtual Expression* clone() = 0;
virtual ~Expression(){}
};
//functor for Constant_1 expression
// functor for Constant_1 expression
struct Constant_1 : Expression{
Constant_1 (const double& d): d_(d){}
double operator()(double){ return d_; }
......@@ -20,16 +20,16 @@ struct Constant_1 : Expression{
Expression *clone(){ return new Constant_1(*this); }
};
//functor for Variable_1 expressions
// functor for Variable_1 expressions
struct Variable_1 : Expression{
double operator()(double x){ return x; }
Expression *clone(){ return new Variable_1(*this); }
};
//functor for complex expressions
// functor for complex expressions
template<class Op>
struct ComplexExpression : Expression{
//subtrees
// subtrees
Expression *l_;
Expression *r_;
......@@ -37,7 +37,7 @@ struct ComplexExpression : Expression{
~ComplexExpression(){ delete l_; delete r_; }
double operator()(double d){
//apply Operator vom template
// apply Operator vom template
return Op::apply((*l_)(d), (*r_)(d));
}
};
......@@ -101,7 +101,7 @@ private:
\begin{figure}[h!]
\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)
template<class Func>
double integrate(Func f, double low, double high, double epsilon = 0.001){
assert(low <= high);
......@@ -115,14 +115,14 @@ double integrate(Func f, double low, double high, double epsilon = 0.001){
return (auc1+auc2)/2
}
//add and multiply (schlechte Realisierung, da duplicated code), Entfernung unten mittels type traits
// add and multiply (schlechte Realisierung, da duplicated code), Entfernung unten mittels type traits
struct Add{
static double apply(double l, double r){ return l+r; }
};
struct Multiply{
static double apply(double l, double r){ return l*r; }
};
//operatoren
// operatoren
ExpressionRef operator*(Expression &l, Expression &r){
return ExpressionRef(new ComplexExpression<Multiply>(l, r));
}
......@@ -139,8 +139,8 @@ ExpressionRef operator*(ExpressionRef &l, Expression &r){
return l.getref()*r;
}
//Verwendung mittels dynamic polymorphism
//ruft call operator auf, Auswertung zur Laufzeit, da virtual function
// Verwendung mittels dynamic polymorphism
// ruft call operator auf, Auswertung zur Laufzeit, da virtual function
Variable_1 x;
((2*x*x + 3*x + 3)*(2*x*x + 3*x + 3))(2);
integrate((2*x*2x + 3*x + 3), 0, 1);
......@@ -162,7 +162,7 @@ struct Constant{
struct Variable{
double operator() (double d){ return d; }
};
//für non-terminal, complex expression
// für non-terminal, complex expression
template<class E1, class E2, class Op>
struct ComplexExpr{
ComplexExpr(E1 l, E2 r): l_(l), r_(r){}
......@@ -170,14 +170,14 @@ struct ComplexExpr{
return Op::apply(l_(d), r_(d)); }
E1 l_;E2 r_;
};
//kapselt alle expression objekte, bool gibt an ob non-/literal
// kapselt alle expression objekte, bool gibt an ob non-/literal
template<class E, bool b>
struct Expr{
E e_;
Expr(l& e) : e_(e){}
double operator()(double d){ return e_(d); }
};
//specialisation
// specialisation
template<class E>
struct Expr<E, false>{
double e_;
......@@ -190,7 +190,7 @@ struct Expr<E, true>{
Expr(double const &e) : e_(e){}
double operator()(double d){ return e_; }
};
//arithmetic operators - nur noch einer, da type tracing
// arithmetic operators - nur noch einer, da type tracing
template<class E1, class E2>
Expr<ComplexExpr<Expr<E1,is_arithmetic<E1>::value>,
Expr<E1, is_arithmetic<E2>::value>, Add>,
......@@ -210,7 +210,7 @@ operator+(E1 e1, E2 e2){
\begin{figure}[h!]
\begin{lstlisting}[caption={[Erweiterung zu \cref{lst:extension3_expression_functor}, compile-time + templates]Erweiterung zu \cref{lst:extension3_expression_functor}, compile-time + templates},label=lst:extension4_expression_functor]
//Verwendung mittels static polymorphism
// Verwendung mittels static polymorphism
Variable y;
(<+3.1)(2);
((2*y*y+3*y+3.0)*(2*y*y+3*y+3))(2);
......@@ -240,7 +240,7 @@ Kann buildtime verringern, vermeidet ambiguity, Beispiel \cref{lst:pimpl}
\begin{lstlisting}[caption={[pimpl]pimpl},label=lst:pimpl]
class Map{
private:
struct Impl; //forward decl
struct Impl; // forward decl
shared_ptr<Impl> pimpl_;
};
\end{lstlisting}
......
......@@ -11,14 +11,14 @@
\begin{figure}[h!]
\begin{lstlisting}[caption={[async n stuff]async - erlaubt keine Kommunikation über mehrere Prozesse}, label=lst:async]
int calculate(){ return 42; }
//startet Ausführung sofort
// startet Ausführung sofort
auto future = async(launch::async, calculate, <parameter>);
//startet später, meistens, wenn man das Ergebnis erfragt
// startet später, meistens, wenn man das Ergebnis erfragt
auto future = async(launch::deferred, calculate, <parameter>);
//unspecified policy
// unspecified policy
auto future = async(calculate, <parameter>);
//cout thread-safe gestalten
// cout thread-safe gestalten
cout.sync_with_stdio(true);
atomic<int> counter(0);
......@@ -36,7 +36,7 @@ atomic<int> counter(0);
\begin{lstlisting}[caption={[unique\_lock]unique\_lock}, label=lst:unique_lock]
std::unique_lock<std::mutex>guard1(<someMutex1>, std::defer_lock);
std::unique_lock<std::mutex>guard2(<someMutex2>, std::defer_lock);
//lockt beide gleichzeitig
// lockt beide gleichzeitig
std::lock(guard1, guard2);
......@@ -44,10 +44,10 @@ std::mutex mutex_;
std::condition_variable condVar;
bool dataReady;
std::unique_lock<std::mutex> lck(mutex_);
//wartet bis dataReady true ist
// wartet bis dataReady true ist
condVar.wait(lck, []{return dataReady;});
//notify the waiting ones (in einer anderen Funktion)
// notify the waiting ones (in einer anderen Funktion)
std::lock_guard<std::mutex> lck(mutex_);
dataReady = true;
condVar.notify_all();
......
......@@ -19,14 +19,15 @@ Kann das verbundene Objekt nicht manipulieren
\begin{figure}[h!]
\begin{lstlisting}[caption={Referenzen},label=lst:references]
//ri ist alias für i
// ri ist alias für i
int i = 1; int &ri = i;
//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
double dval = 3.14; int const &ri = dval;
\end{lstlisting}
\end{figure}
......@@ -39,13 +40,13 @@ double dval = 3.14; int const &ri = dval;
\begin{figure}[h!]
\begin{lstlisting}[caption={decltype},label=lst:decltype]
//x und y vom selben Typ
// x und y vom selben Typ
type x; decltype(x) y;
//y ist eine Referenz auf einen Typ wie x
// y ist eine Referenz auf einen Typ wie x
decltype((x))y;
//Referenz zu der Zuweisung
// Typ von D ist eine Referenz, da A=B ein lvalue zurückgibt.
decltype(A=B) D = A;
\end{lstlisting}
\end{figure}
......@@ -12,13 +12,13 @@
\begin{figure}[h!]
\begin{lstlisting}[caption={Expression-Klassen},label=lst:expression_classes]
//g ist lvalue
// g ist lvalue
float &f(){float g; return g;}
//2 ist prvalue
// 2 ist prvalue, da ein rvalue (non reference) zurückgegeben wird
float f(){return 2;}
//2 ist xvalue
// 2 ist xvalue, da ein rvalue reference zurückgegeben wird
float &&f(){return 2;}
\end{lstlisting}
\end{figure}
......@@ -50,26 +50,26 @@ gibt 1 oder 0 aus
\begin{figure}[h!]
\begin{lstlisting}[caption={Implizite Typumwandlung}, label=lst:implict_type_casts]
//long double
// long double
3.14L + 'a'
//int, beide werden zu int promoted, bevor die Operation ausgeführt wird
// int, beide werden zu int promoted, bevor die Operation ausgeführt wird
short+char
//int
// int
unsigned short + int
//unsigned long
// unsigned long
unsigned long + long
\end{lstlisting}
\end{figure}
\ \\[0,4cm]
\indeItem{Einige Print-Preprocessor-Makros}{
\begin{itemize}
\item Einige Print-Preprocessor-Makros
\item \_\_LINE\_\_
\item \_\_FUNCTION\_\_
\item \_\_TIME\_\_
\item \_\_DATE\_\_
\end{itemize}
}
......@@ -6,7 +6,7 @@
\begin{figure}[h!]
\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
uninitialized_fill_n(destination, amount, element)
\end{lstlisting}
\end{figure}
......@@ -70,20 +72,21 @@ uninitialized_fill_n(destination, amount, element) // füllt amount viele Slots
\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.