Could you explain us what std::function<> is all about? |
The
purpose of it is to make higher-order functions (that is, functions which accept or return other functions) more
generic.
It accomplishes this by taking everything that makes sense to "call" and giving it a uniform interface. For the purposes of std::function, things that make sense to "call" model a specification called
Callable:
https://en.cppreference.com/w/cpp/named_req/Callable
Objects that are
Callable include
- Function objects (including pointers to functions and objects like
c below)
- Pointers-to-member-data
- Pointers-to-member-functions
Everything in that list can be "called", but each needs a different syntax.
std::function wraps up anything in that list and provides the same interface for it. It doesn't care about the types of those objects - it only cares about the interface used to call it.
It gives us the ability to treat any object, no matter its type, as the same kind of std::function, as long as it can be called a specific way. This is called
type erasure, which is a kind of runtime polymorphism. This typically implies a small performance penalty, similar to that of a virtual function call.
Exercise:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
#include <functional>
struct A { int f() const { return 1; } };
struct B : A { int x = 2; };
struct C { int operator()(B const& b) const { return b.f(); } };
int main()
{
// Given these variables pf, px, c and d
int (A::*pf)() const = &A::f;
int B::* px = &B::x;
C c;
auto d = [](A const& a) { return a.f(); };
// Step 1:
// Replace "your_type_goes_here" with the right kind of std::function
// The program will compile when you've got it right
your_type_goes_here my_functions[] = { pf, px, c, d };
// Step 2:
// Call pf, px, c, and d individually
// Example: this line of code calls pf:
(B{}.*pf)();
// Step 3:
// Call each element of my_functions:
// Example: this line of code calls my_functions[2]:
my_functions[2](B{});
}
|
Try it here:
https://godbolt.org/z/h47tmP