7

The main reason for function pointers is to provide generic callable objects, but in C++ 11 the way to provide it would be to use std::function, so is there any reason to use function pointers in modern C++ apart from compatibility with C? In other words, is std::function a modern version of function pointers, exactly like std::array vs built-in arrays?

6
  • 1
    why you called function pointers generic callable objects? Commented Oct 15, 2014 at 6:37
  • I meant you can assign different functions with the same signature to one function pointer Commented Oct 15, 2014 at 6:39
  • 1
    There may be efficiency considerations. std::functions have extra indirections and aren't for free. Commented Oct 15, 2014 at 6:39
  • 5
    A std::function object is not equivalent to a function pointer, but you can initialize a std::function object with a function pointer. Instead it's a callable object that can wrap other callable objects, and yes in most cases it's preferred as it can handle all kind of other callable objects (function pointers, member function pointers, lambdas, other callable objects, etc.). Commented Oct 15, 2014 at 6:39
  • 4
    The comparison with std::array is incorrect, std::array has zero overhead compared to a raw array. Commented Oct 15, 2014 at 6:42

4 Answers 4

4

Yes I'd prefer std::function nearly everywhere but there are few cases where size overhead and indirection of std::function may not be acceptable. For small callables like function pointers wrapped in std::function, there is typically no additional indirection and no dynamic memory allocation since the callable fits into the std::function but std::function may be big to hold even bigger callables so there may be a big space overhead.

Sign up to request clarification or add additional context in comments.

3 Comments

When would you use std::function instead of just lambda expressions? When you want to be able to provide other kinds of implementations and you don't want to do that by wrapping them in lambdas?
@Jerry101 Yes like function pointers I use them to switch between different Implementations or to let a caller provide some kind of functionality like a callback. You can't do this with lambdas since every lambda has it's own type.
The main purpose of std::function is type erasure and adaptation. Function pointers have a strict type. std::function is a polymorphic function wrapper, it can bind to a free function, a class static function, a member function, and it can be used for partial function application, etc. If you don't need all of that, it probably isn't the right tool for the job, the type-erasure doesn't come free, often involving virtual calls and heap allocation (although typically there is a small buffer optimisation).
3

To be honest, I can't think of a case where I'd need std::function, and here's why. If I'm bouncing function pointers around at all, then I'm probably working at a very low level. Perhaps the reason is that C++-style inheritance has proven too restrictive so I'm designing my own polymorphism. Alternatively, I might be working on a small embedded controller where I'm really shaving off the bytes. Either way, I'll be relying on myself, and not on the compiler, to remember what types I've got etc. I'd basically be banging metal and want the metal to behave like metal, not like an elevator from Sirius Cybernetics.

The only case where I'm likely to want the overhead of std::function is if I'm trying to do something functional, like juggling closures, but if I want that then I'm unlikely to be using C++ at all.

2 Comments

Java Script is nothing but closures and function pointers. I wouldn't call that programming style "low level". :) Elements of functional programming are potentially useful regardless of how low a level you find yourself on.
anything remotely similar to an event based system would probably be much better with std::function rather than plain function pointers. Passing in void* parameters and casting is not usually preferred :P
1

On POSIX systems you get dlopen & dlsym and you would use them to get function pointers from dynamically loaded plugins.

This is a common use case where function pointers are still useful, even with C++14 (see e.g. Qt)

And as many people observed, the implementation of closures (or of std::function) would often require extra indirections and extra runtime costs.

Comments

1

std::function is very handy and efficient for most use cases. But there is a missing feature: equality.

So, every time you need to compare/filter/search for/sort std::function like objects, you have to fall back to function pointers to implement what you need.

2 Comments

Equality of functions is somehow undecidable, if you care about their observable behavior only
Sure, that's why std::function objects can't be compared)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.