Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Fun with Lambdas: C++14 Style (part 2)

50,792 views

Published on

Look at some interesting examples of C++14 lambdas and how they interact with other language features and libraries.

Published in: Education
  • Sex in your area is here: ❤❤❤ http://bit.ly/33tKWiU ❤❤❤
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Follow the link, new dating source: ♥♥♥ http://bit.ly/33tKWiU ♥♥♥
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • I found this program very useful. The topics are laid out clearly for ease of reference. It is nothing like your usual revision guide because Jeevan's is a well-defined strategy; he shows you exactly what to do to achieve a top grade in GCSE maths, in a step-by-step format. He addresses issues such as how much time should be spent on revision, exam technique, tips for scoring 100%, motivation, freeing up 50% of your time etc. unlike a normal revision guide which is just packed with theory. He also explains concepts with more detail. For instance, I used to find solving equations tricky but after reading his section on algebra, I fully understand how to solve an equation. The DVDs are great because he teaches concepts both verbally and visually which is always helpful!  http://ishbv.com/jeevan91/pdf
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Doctor's 2-Minute Ritual For Shocking Daily Belly Fat Loss! Watch This Video ▲▲▲ https://tinyurl.com/y6qaaou7
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Is foreach guaranteed to call each of the lambdas in order?
    Isn't the order of parameter evaluation for functions undefined in c++ so theoretically you can see

    10
    20.2
    true

    or

    true
    10
    20.2
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

Fun with Lambdas: C++14 Style (part 2)

  1. 1. Sumant Tambe, Ph.D. Microsoft Visual C++ MVP Senior Software Research Engineer Real-Time Innovations, Inc. @sutambe SFBay Association of C/C++ Users April 9, 2014
  2. 2. Author Blogger Open-Source Contributor LEESA Rx4DDS.NET Reflection for DDS-XTypes
  3. 3. » Functional Programming eXchange » Strange Loop » ReactConf » LambdaConf » LambdaJam » CraftConf » MSFT MVP Summit » Qcon NYC/SF/London » Closure West » Spring into Scala » Progressive F# » FP Days » SkillsMatter
  4. 4. » Lambda Expressions ˃ expr.prim.lambda » Anonymous functions void abssort(float* x, unsigned N) { std::sort(x, x + N, [](float a, float b) { return std::abs(a) < std::abs(b); }); }
  5. 5. class Comp { float a; public: Comp(float x) { a = x; } bool compare(float b) const { return std::abs(a) < std::abs(b); } }; float array[5] = { 0, 1, 2, 3, 4 }; float a = 3; Comp f(a); for(float item : array) std::cout << std::boolalpha << f.compare(item);
  6. 6. class Comp { float a; public: Comp(float x) { a = x; } bool operator () (float b) const { return std::abs(a) < std::abs(b); } }; float array[5] = { 0, 1, 2, 3, 4 }; float a = 3; Comp f(a); for(float item : array) std::cout << std::boolalpha << f(item);
  7. 7. class ##### { float a; public: Foo(float x) { a = x; } bool operator () (float b) const { return std::abs(a) < std::abs(b); } }; float array[5] = { 0, 1, 2, 3, 4 }; float a = 3; auto f = #####(a); for(float item : array) std::cout << std::boolalpha << f(item);
  8. 8. class ##### { float a; public: Foo(float x) { a = x; } bool operator () (float b) const { return std::abs(a) < std::abs(b); } }; float array[5] = { 0, 1, 2, 3, 4 }; float a = 3; auto f = #####(a); auto f = [a](float b) { return std::abs(a) < std::abs(b) }; for(float item : array) std::cout << std::boolalpha << f(item);
  9. 9. » Anonymous functions » Written exactly in the place where it's needed » Can access the variables available in the enclosing scope (closure) » May maintain state (mutable or const) » Can be passed to a function » Can be returned from a function » Deduce return type automatically » Accept generic parameter types (only in C++14) [a](auto b) { return std::abs(a) < std::abs(b) };
  10. 10. » Associative containers and lambdas » Recursive Lambdas » Composable list manipulation » Scope Exit Idiom » Overloaded Lambdas » Type Switch (simple pattern matching) » Converting shared_ptr between boost and std » In-place parameter pack expansion » Memoization
  11. 11. » Associative containers: set, map, multiset, multimap ˃ Use comparators ˃ Example, std::set<int, std::less<int>> » Can comparators be a lambda? » std::set<int, ???> » Use std::function as the comparator type std::set<int, std::function<bool(int, int)>> numbers([](int i, int j) { return i < j; }); » Small-closure optimization may kick in ˃ Check you compiler manual
  12. 12. auto make_fibo() { std::function<int(int)> recurse; recurse = [&](int n){ return (n<=2)? 1 : recurse(n-1) + recurse(n-2); }; return recurse; } int main() { auto fibo = make_fibo(); std::cout << fibo(10) << std::endl; // 55 return 0; }
  13. 13. auto make_fibo() { return [](int n) { std::function<int(int)> recurse; recurse = [&](int n){ return (n<=2)? 1 : recurse(n-1) + recurse(n-2); }; return recurse(n); }; } int main() { auto fibo = make_fibo(); std::cout << fibo(10) << std::endl; // 55 return 0; }
  14. 14. IList<Box> boxes = /* ... */; int sumOfWeights = boxes.Where(b => b.Color == Color.RED) .Select(b => b.Weight) .Count(); List<Box> boxes = /* ... */; int sumOfWeights = boxes.stream() .filter(b -> b.getColor() == Color.RED) .map(b -> b.getWeight()) .sum(); C# Java8
  15. 15. » Example cpplinq (http://cpplinq.codeplex.com) Box boxes[] = { … }; int sum_of_weights = cpplinq::from_array(boxes) >> where([](const Box & box) { return box.color == Color.RED; }) >> select([](const Box & box) { return box.get_weight(); }) >> count();
  16. 16. » Restriction Operators ˃ Where » Projection Operators ˃ ref, select, select_many » Partitioning Operators ˃ take, take_while, skip, skip_while » Join Operators ˃ Join » Concatenation Operators ˃ Concat » Ordering Operators ˃ orderby, orderby_ascending or orderby_descending » Set Operators ˃ distinct, union_with, intersect_with, except » Set Operators ˃ distinct, union_with, intersect_with, except » Conversion Operators ˃ to_vector, to_list, to_map, to_lookup » Element Operators ˃ first, first_or_default, last_or_default » Generation Operators ˃ range, repeat, empty, singleton, generate, » Quantifiers ˃ any, all, contains, » Aggregate Operators ˃ Count, sum, min, max, avg, aggregate » Other ˃ pair_wise, zip_with
  17. 17. » Cpplinq http://cpplinq.codeplex.com/ » Narl (Not another range library) https://github.com/essennell/narl » boost.range http://www.boost.org/doc/libs/1_54_0/libs/range/ » Linq http://pfultz2.github.io/Linq/ » boolinq http://code.google.com/p/boolinq/ » lx++ (part of Native-RX) https://rx.codeplex.com/ » Linq++ https://github.com/hjiang/linqxx/ » oven http://p-stade.sourceforge.net/oven/ » cpplinq (same name but unrelated) http://code.google.com/p/cpplinq/ » linq https://bitbucket.org/ronag/cppextras/src/master/linq/linq.hp p
  18. 18. » Language for Embedded Query and Traversal » Tree Traversal ˃ For XML data-binding code generators ˃ Visitors » Think XPath queries embedded in C++ ˃ Typed (not string encoded) » Generic Programming ˃ Expression Templates ˃ Meta-programming ˃ C++ Concepts (no longer in C++11) http://www.dre.vanderbilt.edu/LEESA/
  19. 19. <catalog> <book> <title>…</title> <price>…</price> <author> <name>…</name> <country>…</country> </author> </book> <book>...</book> ... </catalog> LEESA: std::vector<name> author_names = eval(root, catalog() >> book() >> author() >> name()); XPath: "/book/author/name/text()"
  20. 20. » Find names of authors from USA » XPath: “//author[country/text() = ‘USA’]/name/text()” » LEESA: Catalog croot = load_catalog(“catalog.xml”); std::vector<Name> author_names = eval(croot, Catalog() >> DescendantsOf(Catalog(), Author()) >> Select(Author(), [](const Author &a) { return a.get_country() == “USA”; }) >> Name());
  21. 21. int main() { std::mutex m; m.lock(); SCOPE_EXIT(m.unlock()); /* Potential exceptions here */ return 0; } Example only. Prefer std::lock_guard Scope exit idiom ensures that resources are released
  22. 22. template <typename F> struct ScopeExit { ScopeExit(F f) : f(f) {} ~ScopeExit() { f(); } F f; }; template <typename F> ScopeExit<F> MakeScopeExit(F f) { return ScopeExit<F>(f); }; #define DO_STRING_JOIN(arg1, arg2) arg1 ## arg2 #define SCOPE_EXIT(code) auto STRING_JOIN(scope_exit_, __LINE__) = MakeScopeExit([&](){code;})
  23. 23. » Can you really do that!? ˃ As it turns out, YES! template <class... F> struct overload : F... { overload(F... f) : F(f)... {} }; template <class... F> auto make_overload(F... f) { return overload<F...>(f...); } auto f = make_overload([](int i) { /* print */ }, [](double d) { /* print */ }); f(10); f(9.99);
  24. 24. struct Base {}; struct Derived : Base {}; template <class Poly> void test(Poly& p) { match(p)( [](int i) { cout << “int”; }, [](std::string &) { cout << “string”; }, [](Base &) { cout << "Base"; }, [](Derived &) { cout << "Derived"; }, otherwise([](auto x) { cout << "Otherwise”; }) ); } test(10); // int test(std::string(“C++ Truths”)); // string test(Derived()); // Derived test(9.99); // Otherwise
  25. 25. » Boost and std::shared_ptr manage memory automatically » They both use their own reference counters » What happens when you convert from boost to std shared_ptr or vice versa template <typename T> boost::shared_ptr<T> make_shared_ptr(std::shared_ptr<T> ptr) { return boost::shared_ptr<T>(ptr.get()); } » Hint: They both support deleters ˃ malloc = allocator ˃ free = deleter std::shared_ptr<char> buf((char *)malloc(10), free);
  26. 26. template <typename T> boost::shared_ptr<T> make_shared_ptr(std::shared_ptr<T> ptr) { return boost::shared_ptr<T>(ptr.get(), [ptr](T*) mutable { ptr.reset(); }); } template <typename T> std::shared_ptr<T> make_shared_ptr(boost::shared_ptr<T> ptr) { return std::shared_ptr<T>(ptr.get(), [ptr](T*) mutable { ptr.reset(); }); }
  27. 27. void no_op(...) { } template <class... T> void foreach(T... args) { no_op([=](){ cout << args << "n"; return true; }()...); } foreach(10, 20.2, true);
  28. 28. » Avoid repeated calculations by caching function results template <typename ReturnType, typename... Args> auto memoize(ReturnType (*func)(Args...)) int fibo(int) { … } int main() { auto mem_fibo = memoize(fibo); std::cout << “Compute” << mem_fibo(10); std::cout << “Lookup” << mem_fibo(10); }
  29. 29. » Avoid repeated calculations by caching function results template <typename ReturnType, typename... Args> auto memoize(ReturnType (*func)(Args...)) { std::map<std::tuple<Args...>, ReturnType> cache; return ([=](Args... args) mutable { std::tuple<Args...> t(args...); if (cache.find(t) == cache.end()) { std::cout << "not foundn"; cache[t] = func(args...); } return cache[t]; }); }

×