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
0 comments:
Post a Comment