Search code examples
c++pointersc++11function-pointers

modern c++ alternative to function pointers


I've been using function pointers till now, like this format in c++. I do have some uses now and then and I'm wondering is there anything else introduced in c++11/14 as their alternative.

#include <iostream>
using namespace std;

void sayHello();
void someFunction(void f());

int main() {

    someFunction(sayHello);
    return 0;
}
void sayHello(){
    std::cout<<"\n Hello World";
}
void someFunction(void f()){
    f();
} 

I did take a look at this question but couldn't understand any advantages over traditional use of function pointers. Also I would like to ask , is there anything wrong (not recommended) thing with using function pointers since I never see anyone using them. Or any other alternative present.


Solution

  • Also I would like to ask , is there anything wrong (not recommended) thing with using function pointers since I never see anyone using them.

    Yes. Function pointers are terrible, awful things. Firstly, they do not support being generic- so you cannot take a function pointer that, say, takes std::vector<T> for any T. Secondly, they do not support having bound state, so if at any time in the future, anybody, ever, wishes to refer to other state, they are completely screwed. This is especially bad since this includes this for member functions.

    There are two approaches to taking functions in C++11. The first is to use a template. The second is to use std::function.

    The template kinda looks like this:

    template<typename F> void func(F f) {
        f();
    }
    

    The main advantages here are that it accepts any kind of function object, including function pointer, lambda, functor, bind-result, whatever, and F can have any number of function call overloads with any signature, including templates, and it may have any size with any bound state. So it's super-duper flexible. It's also maximally efficient as the compiler can inline the operator and pass the state directly in the object.

    int main() {
        int x = 5;
        func([=] { std::cout << x; });
    }
    

    The main downside here is the usual downsides of templates- it doesn't work for virtual functions and has to be defined in the header.

    The other approach is std::function. std::function has many of the same advantages- it can be any size, bind to any state, and be anything callable, but trades a couple off. Mainly, the signature is fixed at type definition time, so you can't have a std::function<void(std::vector<T>)> for some yet-to-be-known T, and there may also be some dynamic indirection/allocation involved (if you can't SBO). The advantage of this is that since std::function is a real concrete type, you can pass it around as with any other object, so it can be used as a virtual function parameter and such things.

    Basically, function pointers are just incredibly limited and can't really do anything interesting, and make the API incredibly unflexible. Their abominable syntax is a piss in the ocean and reducing it with a template alias is hilarious but pointless.