Fun with Lambdas: C++14 Style (part 2)
Look at some interesting examples of C++11/14 lambdas and how they interact with other language features and libraries. I hope to find some time to add some explanations. See part 1 if you missed it.
- Associative containers and lambdas
std::set<int, std::function<bool(int, int)>> numbers([](int i, int j) { return i < j; });
- Recursive Lambdas (see Creating recursive lambdas and returning them too!)
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); }; }
- Composable list manipulation (e.g., cpplinq, narl, LEESA)
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(); }) >> sum();
- Overloaded Lambdas
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); // int f(9.99); // double
- Type Switch (simple pattern matching) (see type_switch.cpp and this paper)
struct Base { virtual ~Base() {} }; struct Derived : Base {}; template <class Poly> void test(Poly& p) { match(p)( [](int i) { cout << "int"; }, [](std::string &) { cout << "string"; }, [](Derived &) { cout << "Derived"; }, [](Base &) { cout << "Base"; }, otherwise([](auto x) { cout << "Otherwise"; }) ); } Derived d; Base &b = d; std::string cpptruths = "C++ Truths"; boost::any something = cpptruths; test(10); // int test(cpptruths); // string test(something); // string test(b); // Derived test(9.99); // Otherwise
- Converting shared_ptr between boost and std (see StackOverflow)
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(); }); }
- In-place parameter pack expansion
template <class... T> void foreach(T... args) { bool b[] = { [=](){ std::cout << args << "\n"; return true; }()... }; } foreach(10, 20.2, true);
- Memoization (see original)
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 found\n"; cache[t] = func(args...); } return cache[t]; }); }
- Finally, slides