|
1 |
| -- [Callbacks](#callbacks) |
2 |
| - * [Function pointers (including pointers to member functions)](#function-pointers--including-pointers-to-member-functions-) |
3 |
| - * [std::function](#std--function) |
4 |
| - * [Lambda expressions](#lambda-expressions) |
5 |
| - * [Bind expressions](#bind-expressions) |
6 |
| - * [Function objects (classes with overloaded function call operator operator())](#function-objects--classes-with-overloaded-function-call-operator-operator---) |
7 |
| -- [Sending a function as parameter to an other function](#sending-a-function-as-parameter-to-an-other-function) |
8 |
| - |
9 |
| - |
10 | 1 | # Callbacks
|
11 | 2 |
|
12 |
| -A callback is a callable accepted by a class or function, used to customize the current logic depending on that callback. `std::invoke` is a generic way to activate any callable. `std::invoke` takes something callable, and arguments to call it with, and does the call. `std::invoke( f, args... )` is a slight generalization of typing `f(args...)` that also handles a few additional cases. |
13 |
| - |
14 |
| -## Function pointers (including pointers to member functions) |
15 |
| -## std::function |
16 |
| -Class template std::function is a general-purpose polymorphic function wrapper. Instances of std::function can store, copy, and invoke any Callable target: |
17 |
| -1. functions |
18 |
| -2. lambda expressions |
19 |
| -3. bind expressions |
20 |
| -4. functors |
| 3 | +A callback function is a callable passed as an argument to a class or function, used to customize the current logic depending on that callback. |
| 4 | +For instance imagine you have a class for modeling a robot and you want to give this freedom to user to define and use different motion planner. You can ask the user to pass the solver function to the robot class so the robot class use that one for moving around. |
21 | 5 |
|
22 | 6 | ```cpp
|
23 |
| -void print(int value) |
24 |
| -{ |
25 |
| - std::cout<< value<<std::endl; |
26 |
| -} |
27 |
| -``` |
| 7 | +typedef std::function<std::vector<double>(double, double)> CallbackFunction; |
28 | 8 |
|
29 |
| -storing a functions: |
30 |
| -```cpp |
31 |
| -std::function<void(int)> funcPrint=print; |
32 |
| -funcPrint(3); |
33 |
| -``` |
| 9 | +class robot { |
34 | 10 |
|
35 |
| -store a bind expressions: |
| 11 | +public: |
| 12 | + CallbackFunction m_callback; |
36 | 13 |
|
37 |
| -```cpp |
38 |
| -std::function<void (int)> funcPrint=std::bind(&print,std::placeholders::_1); |
39 |
| -std::function<void (int)> f(funcPrint); |
40 |
| -f(3); |
41 |
| -``` |
| 14 | + void makeMotion(std::vector<double> trajectory) { |
| 15 | + std::cout << "robot is traversing the generated trajectory:" << std::endl; |
| 16 | + for (const auto &p : trajectory) |
| 17 | + std::cout << p << std::endl; |
| 18 | + } |
42 | 19 |
|
43 |
| -store lambda expressions: |
44 |
| -```cpp |
45 |
| -auto lambda=[](int value){std::cout<< value<<std::endl;}; |
46 |
| -std::function<void(int)>f(lambda); |
47 |
| -f(3); |
48 |
| -``` |
| 20 | + void move(double start, double goal) { |
49 | 21 |
|
50 |
| -store a functors: |
51 |
| -```cpp |
52 |
| -void (*printfunctor)(int); |
53 |
| -printfunctor=print; |
54 |
| -std::function<void(int)>f(printfunctor); |
55 |
| -f(3); |
| 22 | + std::vector<double> trajectory = m_callback(start, goal); |
| 23 | + makeMotion(trajectory); |
| 24 | + } |
| 25 | +}; |
56 | 26 | ```
|
57 | 27 |
|
58 |
| -## Lambda expressions |
59 |
| -## Bind expressions |
60 |
| -`std::bind` works as a Functional Adaptor i.e. it takes a function as input and returns a new function Object as an output with with one or more of the arguments of passed function bound or rearranged (partial function application). |
| 28 | +Now we can have different solvers: |
61 | 29 |
|
62 |
| -first example: |
63 | 30 | ```cpp
|
64 |
| -void print(int firstParam, int secondParam) |
65 |
| -{ |
66 |
| - std::cout << "First Param is: " << firstParam << " Second Param is: " << secondParam << std::endl; |
| 31 | +std::vector<double> planer1(double start, double goal) { |
| 32 | + return {start, (start + goal) / 2, goal}; |
| 33 | +} |
| 34 | +std::vector<double> planer2(double start, double goal) { |
| 35 | + return {start, start + (start + goal) / 3, 2 * (start + goal) / 3, goal}; |
67 | 36 | }
|
68 | 37 | ```
|
69 |
| -in the main: |
| 38 | +Now we can assign and use different solvers: |
| 39 | + |
70 | 40 | ```cpp
|
71 |
| -int firstParam=3; |
72 |
| -int secondParam=5; |
73 |
| -auto MyPrinter=std::bind(&print,firstParam,secondParam); |
74 |
| -MyPrinter(); |
| 41 | +robot myrobot1; |
| 42 | +myrobot1.m_callback = planer1; |
| 43 | +myrobot1.move(start, goal); |
75 | 44 | ```
|
76 |
| -You can use `std::placeholders::_` to set the order of the parameters: |
| 45 | + |
| 46 | +or |
77 | 47 |
|
78 | 48 | ```cpp
|
79 |
| -auto reversePrintFunc = std::bind(&print, std::placeholders::_2, std::placeholders::_1); |
80 |
| - |
81 |
| -int firstParam = 3; |
82 |
| -int secondParam = 5; |
83 |
| - |
84 |
| -print(firstParam, secondParam); |
85 |
| -reversePrintFunc(firstParam, secondParam); |
| 49 | +std::function<std::vector<double>(double, double)> planer2_ptr = |
| 50 | + std::bind(&planer2, std::placeholders::_1, std::placeholders::_2); |
86 | 51 |
|
| 52 | +myrobot1.m_callback = planer2_ptr; |
| 53 | +myrobot1.move(start, goal); |
87 | 54 | ```
|
88 |
| -You can use it like a lambda expression: |
89 | 55 |
|
| 56 | +or |
90 | 57 |
|
91 | 58 | ```cpp
|
92 |
| -std::vector<int> vec={1,2,3}; |
93 |
| -std::vector<int> values(vec.size(),0); |
94 |
| -
|
95 |
| -// raise every value in vec to the power of 3 |
96 |
| -auto f=std::bind(&std::pow<int,int>,std::placeholders::_1,3); |
97 |
| -std::transform(vec.begin(), vec.end(), values.begin(), f); |
98 |
| - |
99 |
| -for(auto value:values) |
100 |
| - std::cout<< value<<std::endl; |
101 |
| -``` |
102 |
| -an other example: |
| 59 | + auto planer_lambda = [](double start, double goal) { |
| 60 | + return std::vector<double>(10, 2); |
| 61 | + }; |
103 | 62 |
|
104 |
| -```cpp |
105 |
| -int param=3; |
106 |
| -auto printer=std::bind(&printTemplate<int>,param); |
| 63 | + myrobot1.m_callback = planer_lambda; |
| 64 | + myrobot1.move(start, goal); |
107 | 65 | ```
|
108 |
| -or |
109 |
| -```cpp |
110 |
| -auto printer=std::bind(&printTemplate<int>,std::placeholders::_1); |
111 |
| -``` |
112 |
| -an calling it: |
113 |
| -```cpp |
114 |
| -std::function<void (int)>f(printer); |
115 |
| -f(param); |
116 |
| -``` |
117 |
| -
|
118 |
| -
|
119 |
| -Refs: [1](//https://www.youtube.com/watch?v=ZlHi8txU4aQ) |
| 66 | +[code](../src/callbacks.cpp) |
120 | 67 |
|
121 |
| -[code](../src/bind.cpp) |
| 68 | + |
122 | 69 |
|
| 70 | +Refs: [1](https://stackoverflow.com/questions/2298242/callback-functions-in-c) |
123 | 71 |
|
124 |
| -Refs: [1](https://stackoverflow.com/questions/2298242/callback-functions-in-c), [2](https://stackoverflow.com/questions/6610046/stdfunction-and-stdbind-what-are-they-and-when-should-they-be-used), [2](https://en.wikipedia.org/wiki/Partial_application) |
125 |
| -[source code](../src/callbacks.cpp) |
126 | 72 |
|
127 | 73 |
|
128 | 74 |
|
0 commit comments