Commit c8544743 authored by me's avatar me
Browse files

clarified some statements and improved visual decisions

parent 3bc64fad
...@@ -13,12 +13,12 @@ ...@@ -13,12 +13,12 @@
\begin{figure}[h!] \begin{figure}[h!]
\begin{lstlisting}[caption={[Template Specialisation]Template Specialisation - Partial Specialisation ist nur bei Klassen erlaubt}, label=lst:template_specialisation] \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(){} 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>(){} 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>(){} 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, typename T2> class Y{};
template<typename T1> classY<T1, int>{}; template<typename T1> classY<T1, int>{};
\end{lstlisting} \end{lstlisting}
...@@ -31,7 +31,7 @@ template <typename T> void f3(T*){} ...@@ -31,7 +31,7 @@ template <typename T> void f3(T*){}
template <> void f3<int*>(int* a){} template <> void f3<int*>(int* a){}
int* ip = new int[2]; 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); f3(ip);
\end{lstlisting} \end{lstlisting}
\end{figure} \end{figure}
...@@ -44,7 +44,7 @@ template<typename T1, typename T2>class Y{ ...@@ -44,7 +44,7 @@ template<typename T1, typename T2>class Y{
public: public:
template<typename TT>void print(TT t); 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> template<typename T1, typename T2>template<typename TT>
void Y <T1, T2>::print(TT); void Y <T1, T2>::print(TT);
\end{lstlisting} \end{lstlisting}
...@@ -55,12 +55,12 @@ void Y <T1, T2>::print(TT); ...@@ -55,12 +55,12 @@ void Y <T1, T2>::print(TT);
\begin{lstlisting}[caption={typename als Hilfe zur Konfliktauflösung}, label=lst:typename_solves_conflicts] \begin{lstlisting}[caption={typename als Hilfe zur Konfliktauflösung}, label=lst:typename_solves_conflicts]
template<typename T1>class X{ template<typename T1>class X{
public: 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 // 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; // T::mem *p1;
//das hier sind die beiden Dinge, die für sich genommen funktionieren // 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 static int const i = T::mem *p; // T::mem muss eine Variable sein
typename T::mem *p1; //T::mem muss ein type sein typename T::mem *p1; // T::mem muss ein type sein
}; };
\end{lstlisting} \end{lstlisting}
\end{minipage} \end{minipage}
...@@ -77,7 +77,7 @@ auto fcn(It beg, It end)->decltype(*beg){return *beg;} ...@@ -77,7 +77,7 @@ auto fcn(It beg, It end)->decltype(*beg){return *beg;}
} }
\begin{figure}[h!] \begin{figure}[h!]
\begin{lstlisting}[caption={Forwarding Beispiel}, label=lst:forwarding_example] \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> template<typename F, typename T1, typename T2>
void flip(F f, T1 &&t1, T2 &&t2){ void flip(F f, T1 &&t1, T2 &&t2){
f(std::forward<T2>(t2),std::forward<T1>(t1)); f(std::forward<T2>(t2),std::forward<T1>(t1));
......
...@@ -24,13 +24,13 @@ emplace: Legt das Objekt erst im Container an ...@@ -24,13 +24,13 @@ emplace: Legt das Objekt erst im Container an
\begin{figure}[h!] \begin{figure}[h!]
\begin{lstlisting}[caption={Stream-Flush}, label=lst:flush_of_streams] \begin{lstlisting}[caption={Stream-Flush}, label=lst:flush_of_streams]
//string, flush // string, flush
cout << " " << flush; cout << " " << flush;
//string, null, flush // string, null, flush
cout << " " << ends; cout << " " << ends;
//aktiviere unmittelbare Flush-Operationen nach input // aktiviere unmittelbare Flush-Operationen nach input
cout << unitbuf; cout << unitbuf;
\end{lstlisting} \end{lstlisting}
\end{figure} \end{figure}
...@@ -27,13 +27,13 @@ class Loop{ ...@@ -27,13 +27,13 @@ class Loop{
public: public:
template<typename Container> template<typename Container>
static void run(Container &v){ 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); v.push_back(T<beg>::value);
Loop<beg+1,end,T>::run(v); Loop<beg+1,end,T>::run(v);
} }
}; };
//template specialisation, Abbruchbedingung // template specialisation, Abbruchbedingung
template<unsigned long end, template<unsigned long>class T> template<unsigned long end, template<unsigned long>class T>
class Loop<end,end, T>{ class Loop<end,end, T>{
public: public:
...@@ -46,18 +46,18 @@ template<unsigned long N> ...@@ -46,18 +46,18 @@ template<unsigned long N>
class Fibonacci{ class Fibonacci{
public: public:
static const int value = Fibonacci<N-2>::value+Fibonacci<N-1>::value; static const int value = Fibonacci<N-2>::value+Fibonacci<N-1>::value;
//alternativ // alternativ
enum{value2 = Fibonacci<N-2>::value2 + Fibonacci<N-1>::value2}; enum{value2 = Fibonacci<N-2>::value2 + Fibonacci<N-1>::value2};
}; };
//specialisation 0 // specialisation 0
template<> template<>
class Fibonacci<0u>{ class Fibonacci<0u>{
public: public:
static const int value = 0; static const int value = 0;
enum{value2 = 0}; enum{value2 = 0};
}; };
//specialisation 1 // specialisation 1
template<> template<>
class Fibonacci<1u>{ class Fibonacci<1u>{
public: public:
......
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
\begin{figure}[h!] \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] \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()); 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()); 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()); words.erase(endunique, words.end());
\end{lstlisting} \end{lstlisting}
\end{figure} \end{figure}
...@@ -12,9 +12,9 @@ words.erase(endunique, words.end()); ...@@ -12,9 +12,9 @@ words.erase(endunique, words.end());
\begin{figure}[h!] \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] \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) // syntax: auto newCallable = bind(callable,arg_list)
#include <functional> //std::ref #include <functional> // std::ref
using namespace std::placeholders; //_1 using namespace std::placeholders; // _1
string s; string s;
vector<string>words; vector<string>words;
...@@ -23,7 +23,7 @@ while(cin >> s) ...@@ -23,7 +23,7 @@ while(cin >> s)
for_each(words.begin(),words.end(), for_each(words.begin(),words.end(),
bind(print,ref(cout),_1, ' ')); 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(), for_each(words.begin(),words.end(),
[](string s){cout << s << " ";})); [](string s){cout << s << " ";}));
...@@ -47,11 +47,11 @@ for_each(in, eof, bind(print, ref(cout), _1, '\n')); ...@@ -47,11 +47,11 @@ for_each(in, eof, bind(print, ref(cout), _1, '\n'));
\begin{figure}[h!] \begin{figure}[h!]
\begin{lstlisting}[caption={Insert iterator}, label=lst:insert_iterator] \begin{lstlisting}[caption={Insert iterator}, label=lst:insert_iterator]
vector<int> vec; vector<int> vec;
//insert elements at the tail // insert elements at the tail
auto it = back_inserter(vec); auto it = back_inserter(vec);
//equivalent to vec.push_back(42) // equivalent to vec.push_back(42)
*it = 42; *it = 42;
//front_inserter verwendet push_front // front_inserter verwendet push_front
\end{lstlisting} \end{lstlisting}
\end{figure} \end{figure}
...@@ -85,7 +85,7 @@ int i; ...@@ -85,7 +85,7 @@ int i;
while(cin >> i) while(cin >> i)
vi.push_back(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(), transform(vi.begin(), vi.end(), vi.begin(),
[](int i){return i < 0 ? -i : i;}); [](int i){return i < 0 ? -i : i;});
\end{lstlisting} \end{lstlisting}
...@@ -94,34 +94,34 @@ transform(vi.begin(), vi.end(), vi.begin(), ...@@ -94,34 +94,34 @@ transform(vi.begin(), vi.end(), vi.begin(),
\begin{figure}[h!] \begin{figure}[h!]
\begin{lstlisting}[caption={Vector-Dinge: fill, fill\_n, accumulate, copy}, label=lst:vector_stuff] \begin{lstlisting}[caption={Vector-Dinge: fill, fill\_n, accumulate, copy}, label=lst:vector_stuff]
vector<int> vec(10); //initialises to 0 per default vector<int> vec(10); // initialises to 0 per default
fill(vec.begin(), vec.end(), 1); //set all values to 1 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. // 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 // aufsummieren aller Werte, wobei die Summe mit 0 beginnt
int sum = accumulate(vec.cbegin(), vec.cend(), 0); 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.); 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); fill_n(back_inserter(vec), 10, 42);
//accumulate funktioniert auch auf Strings // accumulate funktioniert auch auf Strings
vector<string> v; vector<string> v;
... ...
string concat = accumulate(v.cbegin(), v.cend(), string("")); string concat = accumulate(v.cbegin(), v.cend(), string(""));
//Initialisierung mittels istream_iterator // Initialisierung mittels istream_iterator
istream_iterator<int> in_iter(cin), eof; istream_iterator<int> in_iter(cin), eof;
vector<int> vec(in_iter, eof); vector<int> vec(in_iter, eof);
//Ausgabe mittels ostream_itertor // Ausgabe mittels ostream_itertor
ostream_iterator<int> out_iter(cout, " " ); ostream_iterator<int> out_iter(cout, " " );
copy(vec.begin(), vec.end(), out_iter); copy(vec.begin(), vec.end(), out_iter);
//alternativ // alternativ
for(auto e: vec) for(auto e: vec)
*out_iter++ = e; *out_iter++ = e;
\end{lstlisting} \end{lstlisting}
...@@ -152,8 +152,8 @@ unordered\_map, unordered\_set, unordered\_multimap, unordered\_multiset ...@@ -152,8 +152,8 @@ unordered\_map, unordered\_set, unordered\_multimap, unordered\_multiset
\begin{figure}[h!] \begin{figure}[h!]
\begin{lstlisting}[caption={Container Dinge}, label=lst:container_stuff] \begin{lstlisting}[caption={Container Dinge}, label=lst:container_stuff]
//count the number of times each word occurs in the input // count the number of times each word occurs in the input
//map from string to size_t // map from string to size_t
map<string, size_t> word_count; map<string, size_t> word_count;
string word; string word;
while(cin >> word) while(cin >> word)
......
...@@ -31,21 +31,21 @@ f(t1,t2); ...@@ -31,21 +31,21 @@ f(t1,t2);
\begin{figure}[h!] \begin{figure}[h!]
\begin{lstlisting}[caption={Exception safe durch Trennung der Instruktionen}, label=lst:exception_stuff] \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(){ template<typename T> T Stack<T>::pop(){
if(!vused) if(!vused)
throw std::runtime_error("pop from empty stack"); throw std::runtime_error("pop from empty stack");
else{ else{
//man verliert bei einem Fehler Elemente // man verliert bei einem Fehler Elemente
T result = v[vused-1]; 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; --vused;
return result; return result;
} }
} }
//Also in einzelne Operationen spalten // Also in einzelne Operationen spalten
template<typename T> T&Stack<T>::top(){ template<typename T> T&Stack<T>::top(){
if(!vused) if(!vused)
throw std::runtime_error("empty stack"); throw std::runtime_error("empty stack");
......
...@@ -5,7 +5,7 @@ int a, b; ...@@ -5,7 +5,7 @@ int a, b;
int first, second, third, fourth; int first, second, third, fourth;
auto tup3 = tie(first, second, third, fourth) = std::make_tuple(1001, 1002, 1003, 1004); auto tup3 = tie(first, second, third, fourth) = std::make_tuple(1001, 1002, 1003, 1004);
tie(std::ignore, a, std::ignore, b) = tup3; tie(std::ignore, a, std::ignore, b) = tup3;
//mutation des Elements first // mutation des Elements first
get<0>(tup3) = 2; get<0>(tup3) = 2;
\end{lstlisting} \end{lstlisting}
\end{figure} \end{figure}
...@@ -13,13 +13,13 @@ get<0>(tup3) = 2; ...@@ -13,13 +13,13 @@ get<0>(tup3) = 2;
\begin{figure}[h!] \begin{figure}[h!]
\begin{lstlisting}[caption={Regex},label=lst:regex] \begin{lstlisting}[caption={Regex},label=lst:regex]
emailDescription = "......."; emailDescription = ".......";
//regex for email address // regex for email address
string regExprStr(R"((\w+(\.|_)?\w*)@(\w+\.\w+)+))"); string regExprStr(R"((\w+(\.|_)?\w*)@(\w+\.\w+)+))");
//regex holder // regex holder
regex rgx(regExprStr); regex rgx(regExprStr);
//search result holder // search result holder
smatch smatch; 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)){ if(regex_search(emailDescription, smatch, rgx)){
cout << "whole adress: " << smatch[0] << "\n"; cout << "whole adress: " << smatch[0] << "\n";
cout << "local part (before @): " << smatch[1] << "\n"; cout << "local part (before @): " << smatch[1] << "\n";
...@@ -28,7 +28,7 @@ if(regex_search(emailDescription, smatch, rgx)){ ...@@ -28,7 +28,7 @@ if(regex_search(emailDescription, smatch, rgx)){
cout << "string after the match: " << smatch.postfix() << "\n"; 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); sregex_token_iterator itBegin(emailDescription.begin(), emailDescription.end(), regExprStr);
const sregex_token_iterator itEnd; const sregex_token_iterator itEnd;
while(itBegin != itEnd) while(itBegin != itEnd)
...@@ -47,19 +47,19 @@ Für Templates sollten nach Möglichkeit stets static\_assert s verwendet werden ...@@ -47,19 +47,19 @@ Für Templates sollten nach Möglichkeit stets static\_assert s verwendet werden
list<int> allOdd; list<int> allOdd;
deque<int> allEven; deque<int> allEven;
vector<int> myVec = ...; 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(), partition_copy(myVec.begin(), myVec.end(),
back_inserter(allOdd), back_inserter(allEven), back_inserter(allOdd), back_inserter(allEven),
[](int i){return i % 2;}); [](int i){return i % 2;});
//weitere funktionen // weitere funktionen
//true falls alle Elemente ungerade // true falls alle Elemente ungerade
bool b = all_of(myVec.begin(), myVec.end(), bool b = all_of(myVec.begin(), myVec.end(),
[](int i){return i%2;}); [](int i){return i%2;});
//true falls alle Elemente gerade // true falls alle Elemente gerade
bool c = none_of(myVec.begin(),myVec.end(), bool c = none_of(myVec.begin(),myVec.end(),
[](int i){return i%2;}); [](int i){return i%2;});
//kopiert alle ungeraden Elemente nach cout // kopiert alle ungeraden Elemente nach cout
copy_if(myVec.begin(), myVec.end(), copy_if(myVec.begin(), myVec.end(),
ostream_iterator<int>(cout, " "), [](int i) {return i%2;}); ostream_iterator<int>(cout, " "), [](int i) {return i%2;});
// })})})}) <- fix vim-hightlighting // })})})}) <- fix vim-hightlighting
......
...@@ -6,13 +6,13 @@ ...@@ -6,13 +6,13 @@
\begin{figure}[h!] \begin{figure}[h!]
\begin{lstlisting}[caption={[Expression Functor, run-time]Expression Functor, run-time},label=lst:expression_functor] \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{ struct Expression{
virtual double operator() (double) = 0; virtual double operator() (double) = 0;
virtual Expression* clone() = 0; virtual Expression* clone() = 0;
virtual ~Expression(){} virtual ~Expression(){}
}; };
//functor for Constant_1 expression // functor for Constant_1 expression
struct Constant_1 : Expression{ struct Constant_1 : Expression{
Constant_1 (const double& d): d_(d){} Constant_1 (const double& d): d_(d){}
double operator()(double){ return d_; } double operator()(double){ return d_; }
...@@ -20,16 +20,16 @@ struct Constant_1 : Expression{ ...@@ -20,16 +20,16 @@ struct Constant_1 : Expression{
Expression *clone(){ return new Constant_1(*this); } Expression *clone(){ return new Constant_1(*this); }
}; };
//functor for Variable_1 expressions // functor for Variable_1 expressions
struct Variable_1 : Expression{ struct Variable_1 : Expression{
double operator()(double x){ return x; } double operator()(double x){ return x; }
Expression *clone(){ return new Variable_1(*this); } Expression *clone(){ return new Variable_1(*this); }
}; };
//functor for complex expressions // functor for complex expressions
template<class Op> template<class Op>
struct ComplexExpression : Expression{ struct ComplexExpression : Expression{
//subtrees // subtrees
Expression *l_; Expression *l_;
Expression *r_; Expression *r_;
...@@ -37,7 +37,7 @@ struct ComplexExpression : Expression{ ...@@ -37,7 +37,7 @@ struct ComplexExpression : Expression{
~ComplexExpression(){ delete l_; delete r_; } ~ComplexExpression(){ delete l_; delete r_; }
double operator()(double d){ double operator()(double d){
//apply Operator vom template // apply Operator vom template
return Op::apply((*l_)(d), (*r_)(d)); return Op::apply((*l_)(d), (*r_)(d));
} }
}; };
...@@ -101,7 +101,7 @@ private: ...@@ -101,7 +101,7 @@ private:
\begin{figure}[h!] \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] \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> template<class Func>
double integrate(Func f, double low, double high, double epsilon = 0.001){ double integrate(Func f, double low, double high, double epsilon = 0.001){
assert(low <= high); assert(low <= high);
...@@ -115,14 +115,14 @@ double integrate(Func f, double low, double high, double epsilon = 0.001){ ...@@ -115,14 +115,14 @@ double integrate(Func f, double low, double high, double epsilon = 0.001){
return (auc1+auc2)/2 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{ struct Add{
static double apply(double l, double r){ return l+r; } static double apply(double l, double r){ return l+r; }
}; };
struct Multiply{ struct Multiply{
static double apply(double l, double r){ return l*r; } static double apply(double l, double r){ return l*r; }
}; };
//operatoren // operatoren
ExpressionRef operator*(Expression &l, Expression &r){ ExpressionRef operator*(Expression &l, Expression &r){
return ExpressionRef(new ComplexExpression<Multiply>(l, r)); return ExpressionRef(new ComplexExpression<Multiply>(l, r));
} }
...@@ -139,8 +139,8 @@ ExpressionRef operator*(ExpressionRef &l, Expression &r){ ...@@ -139,8 +139,8 @@ ExpressionRef operator*(ExpressionRef &l, Expression &r){
return l.getref()*r; return l.getref()*r;
} }
//Verwendung mittels dynamic polymorphism // Verwendung mittels dynamic polymorphism
//ruft call operator auf, Auswertung zur Laufzeit, da virtual function // ruft call operator auf, Auswertung zur Laufzeit, da virtual function
Variable_1 x; Variable_1 x;
((2*x*x + 3*x + 3)*(2*x*x + 3*x + 3))(2); ((2*x*x + 3*x + 3)*(2*x*x + 3*x + 3))(2);
integrate((2*x*2x + 3*x + 3), 0, 1); integrate((2*x*2x + 3*x + 3), 0, 1);
...@@ -162,7 +162,7 @@ struct Constant{ ...@@ -162,7 +162,7 @@ struct Constant{
struct Variable{ struct Variable{
double operator() (double d){ return d; } 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> template<class E1, class E2, class Op>
struct ComplexExpr{ struct ComplexExpr{
ComplexExpr(E1 l, E2 r): l_(l), r_(r){} ComplexExpr(E1 l, E2 r): l_(l), r_(r){}
...@@ -170,14 +170,14 @@ struct ComplexExpr{ ...@@ -170,14 +170,14 @@ struct ComplexExpr{
return Op::apply(l_(d), r_(d)); } return Op::apply(l_(d), r_(d)); }
E1 l_;E2 r_; 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> template<class E, bool b>
struct Expr{ struct Expr{
E e_; E e_;
Expr(l& e) : e_(e){} Expr(l& e) : e_(e){}
double operator()(double d){ return e_(d); } double operator()(double d){ return e_(d); }
}; };
//specialisation // specialisation
template<class E> template<class E>
struct Expr<E, false>{ struct Expr<E, false>{
double e_; double e_;
...@@ -190,7 +190,7 @@ struct Expr<E, true>{ ...@@ -190,7 +190,7 @@ struct Expr<E, true>{
Expr(double const &e) : e_(e){} Expr(double const &e) : e_(e){}
double operator()(double d){ return 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> template<class E1, class E2>
Expr<ComplexExpr<Expr<E1,is_arithmetic<E1>::value>, Expr<ComplexExpr<Expr<E1,is_arithmetic<E1>::value>,
Expr<E1, is_arithmetic<E2>::value>, Add>, Expr<E1, is_arithmetic<E2>::value>, Add>,
...@@ -210,7 +210,7 @@ operator+(E1 e1, E2 e2){ ...@@ -210,7 +210,7 @@ operator+(E1 e1, E2 e2){
\begin{figure}[h!] \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] \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; Variable y;
(<+3.1)(2); (<+3.1)(2);
((2*y*y+3*y+3.0)*(2*y*y+3*y+3))(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} ...@@ -240,7 +240,7 @@ Kann buildtime verringern, vermeidet ambiguity, Beispiel \cref{lst:pimpl}
\begin{lstlisting}[caption={[pimpl]pimpl},label=lst:pimpl] \begin{lstlisting}[caption={[pimpl]pimpl},label=lst:pimpl]
class Map{ class Map{
private: private:
struct Impl; //forward decl struct Impl; // forward decl
shared_ptr<Impl> pimpl_; shared_ptr<Impl> pimpl_;
};