1<!-- Copyright 2018 Paul Fultz II 2 Distributed under the Boost Software License, Version 1.0. 3 (http://www.boost.org/LICENSE_1_0.txt) 4--> 5 6More examples 7============= 8 9As Boost.HigherOrderFunctions is a collection of generic utilities 10related to functions, there is many useful cases with the library, but a key 11point of many of these utilities is that they can solve these problems with 12much simpler constructs than whats traditionally been done with 13metaprogramming. Lets take look at some of the use cases for using Boost.HigherOrderFunctions. 14 15Initialization 16-------------- 17 18The [`BOOST_HOF_STATIC_FUNCTION`](/include/boost/hof/function) will help initialize function objects at 19global scope, and will ensure that it is initialized at compile-time and (on 20platforms that support it) will have a unique address across translation 21units, thereby reducing executable bloat and potential ODR violations. 22 23In addition, [`BOOST_HOF_STATIC_LAMBDA_FUNCTION`](/include/boost/hof/lambda) allows initializing a lambda 24in the same manner. This allows for simple and compact function definitions 25when working with generic lambdas and function adaptors. 26 27Of course, the library can still be used without requiring global function 28objects for those who prefer to avoid them will still find the library useful. 29 30 31Projections 32----------- 33 34Instead of writing the projection multiple times in algorithms: 35 36 std::sort(std::begin(people), std::end(people), 37 [](const Person& a, const Person& b) { 38 return a.year_of_birth < b.year_of_birth; 39 }); 40 41We can use the [`proj`](/include/boost/hof/by) adaptor to project `year_of_birth` on the comparison 42operator: 43 44 std::sort(std::begin(people), std::end(people), 45 proj(&Person::year_of_birth, _ < _)); 46 47Ordering evaluation of arguments 48-------------------------------- 49 50When we write `f(foo(), bar())`, the standard does not guarantee the order in 51which the `foo()` and `bar()` arguments are evaluated. So with `apply_eval` we 52can order them from left-to-right: 53 54 apply_eval(f, [&]{ return foo(); }, [&]{ return bar(); }); 55 56Extension methods 57----------------- 58 59Chaining many functions together, like what is done for range based libraries, 60can make things hard to read: 61 62 auto r = transform( 63 filter( 64 numbers, 65 [](int x) { return x > 2; } 66 ), 67 [](int x) { return x * x; } 68 ); 69 70It would be nice to write this: 71 72 auto r = numbers 73 .filter([](int x) { return x > 2; }) 74 .transform([](int x) { return x * x; }); 75 76The proposal [N4165](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4165.pdf) 77for Unified Call Syntax(UFCS) would have allowed a function call of `x.f(y)` to become 78`f(x, y)`. However, this was rejected by the comittee. So instead pipable functions can be 79used to achieve extension methods. So it can be written like this: 80 81 auto r = numbers 82 | filter([](int x) { return x > 2; }) 83 | transform([](int x) { return x * x; }); 84 85Now, if some users feel a little worried about overloading the _bitwise or_ 86operator, pipable functions can also be used with [`flow`](/include/boost/hof/flow) like this: 87 88 auto r = flow( 89 filter([](int x) { return x > 2; }), 90 transform([](int x) { return x * x; }) 91 )(numbers); 92 93No fancy or confusing operating overloading and everything is still quite 94readable. 95 96