What is the advantage of std::function<T1(T2)>
over the original T1 (*)(T2)
?
Asked
Active
Viewed 2.1k times
46

Michael Dorst
- 8,210
- 11
- 44
- 71
-
It's more versatile, but also slower. You can't compare `::std::function` instances and it allocates from the heap. – user1095108 Jan 14 '14 at 17:56
-
3@user1095108: It _may_ allocate from the heap. Just like the "small `string` optimization," an implementation may use a "small `function` optimization." – James McNellis Jan 14 '14 at 18:02
-
`may`... a vain hope sometimes. – user1095108 Jan 14 '14 at 20:54
-
There might also be a disadvantage. – user1095108 Aug 10 '14 at 07:40
3 Answers
37
std::function
can hold more than function pointers, namely functors.
#include <functional>
void foo(double){}
struct foo_functor{
void operator()(float) const{}
};
int main(){
std::function<void(int)> f1(foo), f2((foo_functor()));
f1(5);
f2(6);
}
As the example shows, you also don't need the exact same signature, as long as they are compatible (i.e., the parameter type of std::function
can be passed to the contained function / functor).

Xeo
- 129,499
- 52
- 291
- 397
-
4Also, with `std::bind` it is possible to create delegates (i.e. encapsulate a member function pointer with an object) and store them in an std::function, without any difference in handling after creation. This is something that function pointers alone are not capable of. – Tamás Szelei Jul 05 '12 at 21:47
-
2@fish: Well, what `std::bind` returns is a functor, so I wouldn't really special-case that. What can be seen as special is that you can just pass a member function pointer and the `std::function` will make it callable like `f(object, param);`. [Example on Ideone](http://ideone.com/haRtx) – Xeo Jul 05 '12 at 21:49
-
1Another thing is (arguably) easier declarations. Function pointer declarations are a little hard follow due to their C heritage of *"declaration reflecting usage"*-rule. `std::function` objects have a declaration that looks more like a function declaration. (sorry I really should make an edit, but I see that the post is still being updated frequently at this moment. feel free to merge in these). – Tamás Szelei Jul 05 '12 at 21:50
-
yeah, well of course it does. I think it is worth mentioning because delegates are a common pattern in many languages and this is what makes it possible to fluidly replicate them in C++. – Tamás Szelei Jul 05 '12 at 21:52
-
As it is, the program compiles but doesn't do anything. Can I suggest to `cout` the argument in both the function and the functor? And I'd also add a call using a non-integer argument, like `f1(4.7);`. This would show the effect of storing a function accepting a `double` into an `std::function` accepting an `int` parameter. I would also include the output into the answer. I've already prepared the modified code [on Ideone](https://ideone.com/PD9rwW). I can edit your answer myself, if you agree, but I'll do it only with your permission. – Fabio says Reinstate Monica Mar 12 '19 at 12:59
17
std::function
can hold function objects (including lambdas), as well as function pointers with the correct signature. So it is more versatile.

Benjamin Lindley
- 101,917
- 9
- 204
- 274
-
1Side question: I'm assuming the lambdas are called virtually, right? – user541686 Jul 05 '12 at 21:41
-
3@Mehrdad: What is your definition of *called virtually*? – David Rodríguez - dribeas Jul 05 '12 at 21:42
-
@DavidRodríguez-dribeas: An indirect call, i.e. like a `virtual` function. – user541686 Jul 05 '12 at 21:44
-
-
@Mehrdad: It can do that, it could also use a `void*` + a function pointer to a templated function. – Xeo Jul 05 '12 at 21:45
-
3@Mehrdad: `std::function<>` needs to add an indirection to perform the type erasure, so yes, there is one extra level of indirection con calling a lambda through `std::function` (well, calling a lambda or any other thing through `std::function`) – David Rodríguez - dribeas Jul 05 '12 at 21:46
-
-
-
2@anthropomorphic: No, `virtual` means it is *overridable* in derived classes. – celtschk Aug 10 '14 at 07:42
11
Apart from the cleaner look and a more descriptive syntax, std::function
can store any callable object:
- functions
- lambda expressions
- bind expressions
- functors
Not to mention that storing, copying, and binding objects to member functions is much easier and more intuitive.

Michael Dorst
- 8,210
- 11
- 44
- 71

Shoe
- 74,840
- 36
- 166
- 272
-
2Bind expressions simply return functors, so having both functors and bind expressions listed is redundant. – Michael Dorst Aug 10 '14 at 07:32