@ü.li:Listing 1:Partielle Funktionsanwendung mit std::bind, std::function, auto und Lambda-Funktionen @li:1 int addMe(int a, int b){ return a+b; } 2 3 std::function add1= std::bind(addMe,2000,_1); 4 auto add2= []{int b){ return addMe(2000,b); }; 5 auto add3= []{int a){ return addMe(a,11); }; 6 7 addMe(2000,11) == add1(11) == add2(11) == add3(2000); // 2011 @ü.li:Listing 2: Faktorial von 5 zur Übersetzungszeit berechnet @li:1 template 2 struct Factorial{ 3 static int const value= N * Factorial::value; 4 }; 5 6 template <> 7 struct Factorial<1>{ 8 static int const value = 1; 9 }; 10 11 std::cout << Factorial<5>::value << std::endl; 12 std::cout << 120 << std::endl; @ü.li:Listing 3: Dispatch-Table für einfache Arithmetik @li:1 std::map > tab; 2 3 tab.insert( {'+',[](double a,double b){return a + b;}} ); 4 tab.insert( {'-',[](double a,double b){return a - b;}} ); 5 tab.insert( {'*',[](double a,double b){return a * b;}} ); 6 tab.insert( {'/',[](double a,double b){return a / b;}} ); 7 8 std::cout << "3.5+4.5= " << tab['+'](3.5,4.5) << std::endl; // 8 9 std::cout << "3.5*4.5= " << tab['*'](3.5,4.5) << std::endl; // 15.75 10 11 tab.insert( {'^',[](double a,double b){return std::pow(a,b);}} ); 12 std::cout << "3.5^4.5= " << tab['^'](3.5,4.5) << std::endl; // 280.741 @ü.li:Listing 4: Eingabedaten für Haskell und C++ @li:1 // Haskell 2 vec= [1 . . 9] 3 str= ["Programming","in","a","functional","style."] 4 // C++ 5 std::vector vec{1,2,3,4,5,6,7,8,9} 6 std::vectorstr{"Programming","in","a","functional","style."} @ü.li:Listing 5: Vergleich von map und std::transform @li:1 // Haskell 2 map(\a a*a) vec 3 map(\a -> length a) str 3 5 // C++ 6 std::transform(vec.begin(),vec.end(),vec.begin(), 7 [](int i){ return i*i; }); 8 std::transform(str.begin(),str.end(),std::back_inserter(vec2), 9 [](std::string s){ return s.length(); }); 10 11 // [1,4,9,16,25,36,49,64,81] 12 // [11,2,1,10,6] @ü.li:Listing 6: Vergleich von filter und std::remove_if @li:1 // Haskell 2 filter(\x-> x<3 || x>8) vec 3 filter(\x isUpper(head x)) str 4 5 // C++ 6 auto it= std::remove_if(vec.begin(),vec.end(), 7 8 [](int i){ return !((i < 3) or (i > 8)) }); 9 auto it2= std::remove_if(str.begin(),str.end(), 10 [](std::string s){ return !(std::isupper(s[0])); }); 11 12 // [1,2,9] 13 // ["Programming"] @ü.li:Listing 7: Vergleich von foldl und std::accumulate @li:1 // Haskell 2 foldl (\a b a * b) 1 vec 3 foldl (\a b a ++ ":" ++ b ) "" str 4 5 // C++ 6 std::accumulate(vec.begin(),vec.end(),1, 7 [](int a, int b){ return a*b; }); 8 std::accumulate(str.begin(),str.end(),string(""), 9 [](std::string a,std::string b){ return a+":"+b; }); 10 11 // 362800 12 // ":Programming:in:a:functional:style." @ü.li:Listing 8: Konstante Ausdrücke zur Berechnung von Entfernungen @li:1 #include 2 #include 3 4 class Dist{ 5 public: 6 constexpr Dist(long double i):m(i){} 7 8 friend constexpr Dist operator +(const Dist& a, const Dist& b){ 9 return Dist(a.m + b.m); 10 } 11 friend constexpr Dist operator -(const Dist& a,const Dist& b){ 12 return Dist(a.m - b.m); 13 } 14 friend constexpr Dist operator*(double m, const Dist& a){ 15 return Dist(m*a.m); 16 } 17 friend constexpr Dist operator/(const Dist& a, int n){ 18 return Dist(a.m/n); 19 } 20 friend std::ostream& operator<< (std::ostream &out, const Dist& myDist){ 21 out << myDist.m << " m"; 22 return out; 23 } 24 private: 25 long double m; 26 }; 27 28 namespace Unit{ 29 Dist constexpr operator "" _km(long double d){ 30 return Dist(1000*d); 31 } 32 Dist constexpr operator "" _m(long double m){ 33 return Dist(m); 34 } 35 Dist constexpr operator "" _dm(long double d){ 36 return Dist(d/10); 37 } 38 Dist constexpr operator "" _cm(long double c){ 39 return Dist(c/100); 40 } 41 } 42 43 Dist constexpr getAverageDistance(std::initializer_list inList){ 44 auto sum= Dist(0.0); 45 for ( auto i: inList) sum = sum + i; 46 return sum/inList.size(); 47 } 48 49 using namespace Unit; 50 51 int main(){ 52 53 constexpr Dist work= 63.0_km; 54 constexpr Dist workPerDay= 2 * work; 55 constexpr Dist abbreToWork= 5400.0_m; // abbrevation to work 56 constexpr Dist workout= 2 * 1600.0_m; 57 constexpr Dist shop= 2 * 1200.0_m; // shopping 58 59 constexpr Dist distPerWeek1= 4*workPerDay - 3*abbreToWork + workout + shop; 60 constexpr Dist distPerWeek2= 4*workPerDay - 3*abbreToWork + 2*workout; 61 constexpr Dist distPerWeek3= 4*workout + 2*shop; 62 constexpr Dist distPerWeek4= 5*workout + shop; 63 64 constexpr Dist averagePerWeek= getAverageDistance({distPerWeek1,distPerWeek2,distPerWeek3,distPerWeek4}); 65 66 std::cout << "Average per week: " << averagePerWeek << std::endl; 67 68 } @ü.li:Listing 9: Drei reine Funktionen: eine klassische, eine Meta- und eine constexpr-Funktion @li:1 int powFunc(int m, int n){ 2 if (n == 0) return 1; 3 return m * powFunc(m, n-1); 4 } 5 6 template 7 struct PowMeta{ 8 static int const value = m * PowMeta::value; 9 }; 10 11 template 12 struct PowMeta{ 13 static int const value = 1; 14 }; 15 16 constexpr int powConst(int m, int n){ 17 int r = 1; 18 for(int k=1; k<=n; ++k) r*= m; 19 return r; 20 } 21 22 int main(){ 23 std::cout << powFunc(2,10) << std::endl; // 1024 24 std::cout << PowMeta<2,10>::value << std::endl; // 1024 25 std::cout << powConst(2,10) << std::endl; // 1024 26 } @ü.li:Listing 10: Summieren einer Liste in Haskell @li:1 mySum [] = 0 2 mySum (x:xs) = x + mySum xs 3 mySum [1,2,3,4,5] -- 15 @ü.li:Listing 11: Summieren einer variablen Anzahl von Template-Argumenten in C++ @li:1 template 2 struct mySum; 3 4 template<> 5 struct mySum<>{ 6 static const int value= 0; 7 }; 8 9 template 10 struct mySum{ 11 static const int value= head + mySum::value; 12 }; 13 14 int sum= mySum<1,2,3,4,5>::value; // 15 @ü.li:Listing 12: Bedarfsauswertung in Haskell @li:1 length [2+1, 3*2, 1/0, 5-4] -- 4 2 3 successor i= i: (successor (i+1)) 4 take 5 ( successor 1 ) -- [1,2,3,4,5] 5 6 odds= takeWhile (< 1000) . filter odd . map (^2) 7 [1..]= [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 ... Control-C 8 odds [1..] -- [1,9,25, ... , 841,961]