For defination of the std::function, we just need to specify the void and int in its defination.
examples
the flexibility of std::function is the wrapp the different callable in cpp, although it might not a necessary things from the perspective of the system programming, it is good to grasp it for quickly understanding other people’s code.
this is the whole function examples from the cpp references, and I added more comments
#include <functional> #include <iostream> struct Foo { Foo(int num) : num_(num) {} void print_add(int i) const { std::cout << num_+i << '\n'; } int num_; }; void print_num(int i) { std::cout << i << '\n'; } struct PrintNum { void operator()(int i) const { std::cout << i << '\n'; } }; int main() { // store a free function // this is the basic usage of the function as a wrapper // the code is more clean compared with define a function pointer std::function<void(int)> f_display = print_num; f_display(-9); // store a lambda // this may looks more general since we basically do not care about the // type of the input parameter and return parameters // we can call different functions with the lambda expression std::function<void()> f_display_42 = []() { print_num(42); }; f_display_42(); // store the result of a call to std::bind // this may more like the grammar suger and we bind the function with a particular parameter // we can also wrap it by the std::function std::function<void()> f_display_31337 = std::bind(print_num, 31337); f_display_31337(); // store a call to a member function // it looks fancy to call a member function of the instance // the first parameter should be the reference of the instance // we need to use & when assign the member function to the std::function but we do not need the & for the common function previously std::function<void(const Foo&, int)> f_add_display = &Foo::print_add; const Foo foo(314159); f_add_display(foo, 1); f_add_display(314159, 1); // store a call to a data member accessor std::function<int(Foo const&)> f_num = &Foo::num_; std::cout << "num_: " << f_num(foo) << '\n'; // store a call to a member function and object using std::placeholders::_1; std::function<void(int)> f_add_display2 = std::bind( &Foo::print_add, foo, _1 ); f_add_display2(2); // store a call to a member function and object ptr std::function<void(int)> f_add_display3 = std::bind( &Foo::print_add, &foo, _1 ); f_add_display3(3); // store a call to a function object // the PrintNum is a kind of functor in this case that overload the () operator std::function<void(int)> f_display_obj = PrintNum(); f_display_obj(18); }
the key of the map is the identifier of the backend, the value of the map is a std::function wrapper. For this wrapper, the return value is a unique pointer which hold the backend class, and the input parameter is the pipelineFactorArgs.
when we init the map, the code (registration function) looks like this:
template<typename BackendType> class __ColzaBackendRegistration { ... public:
we can see that one anonimous function (lambda function) is used here to wrap the creat function. the BackendType is sent from the template parameter. By this way, we can achieve the creation for anytype of the backend by creating a new backend registration class.