Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between std::function<> and a standard function pointer? [duplicate]

Tags:

c++

c++11

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?

like image 498
aCuria Avatar asked Jan 29 '12 16:01

aCuria


People also ask

What is the major difference between function and function pointer?

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.

What are function pointers and the differences between normal function and function pointers?

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.

Can std :: function be copied?

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.

Why did we need to use an std :: function object?

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.


2 Answers

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.

like image 68
Paul Manta Avatar answered Sep 21 '22 23:09

Paul Manta


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.

like image 44
Kerrek SB Avatar answered Sep 24 '22 23:09

Kerrek SB