Whats the difference between std::function<> and a standard function pointer?
that is:
typedef std::function<int(int)> FUNCTION; typedef int (*fn)(int);
Are they effectively the same thing?
Originally Answered: What is the difference between pointer to function and function pointer? A function pointer points to the memory address, where the function's code is stored. So unlike other functions function pointer points to code rather than data. e.g.
1) Unlike normal pointers, a function pointer points to code, not data. Typically a function pointer stores the start of executable code. 2) Unlike normal pointers, we do not allocate de-allocate memory using function pointers. 3) A function's name can also be used to get functions' address.
You can recover the desired behavior by always using thread-local copies of the std::function because they'll each have an isolated copy of the state variables.
It lets you store function pointers, lambdas, or classes with operator() . It will do conversion of compatible types (so std::function<double(double)> will take int(int) callable things) but that is secondary to its primary purpose.
A function pointer is the address of an actual function defined in C++. An std::function
is a wrapper that can hold any type of callable object (objects that can be used like functions).
struct FooFunctor { void operator()(int i) { std::cout << i; } }; // Since `FooFunctor` defines `operator()`, it can be used as a function FooFunctor func; std::function<void (int)> f(func);
Here, std::function
allows you to abstract away exactly what kind of callable object it is you are dealing with — you don't know it's FooFunctor
, you just know that it returns void
and has one int
parameter.
A real-world example where this abstraction is useful is when you are using C++ together with another scripting language. You might want to design an interface that can deal with both functions defined in C++, as well as functions defined in the scripting language, in a generic way.
Edit: Binding
Alongside std::function
, you will also find std::bind
. These two are very powerful tools when used together.
void func(int a, int b) { // Do something important } // Consider the case when you want one of the parameters of `func` to be fixed // You can used `std::bind` to set a fixed value for a parameter; `bind` will // return a function-like object that you can place inside of `std::function`. std::function<void (int)> f = std::bind(func, _1, 5);
In that example, the function object returned by bind
takes the first parameter, _1
, and passes it to func
as the a
parameter, and sets b
to be the constant 5
.
They are not the same at all. std::function
is a complex, heavy, stateful, near-magic type that can hold any sort of callable entity, while a function pointer is really just a simple pointer. If you can get away with it, you should prefer either naked function pointers or auto
-bind
/auto
-lambda types. Only use std::function
if you really need a systematic way of organizing a heterogeneous collection of callable entities, such as functions, functors, capturing lambdas and bind expressions.
Update: A bit of explanation about auto
types: Compare the following two functions:
void do_something_1(std::function<void(int)> f, int a) { f(a); } template <typename F, typename A> void do_something_2(F f, A a) { f(a); }
Now imagine invoking them with a lambda or a bind
expression:
do_something_X([foo, &bar](int n){ bar += n*foo; }, 12); do_something_X(std::bind(X::bob, &jim, true, _1, Blue), 13);
The second version with the template is more efficient, because in both cases, the argument F
is deduced to the actual, unknowable type of the expression. The first version, with std::function
, isn't a template and may look simpler and more deliberate, but it always forces the construction of the std::function
object, and quite possibly carries multiple type erasure and virtual dispatch costs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With