Modern C ++ alternative to function pointers

I use function pointers so far, like this format in C ++. I have some uses now and then, and I wonder if there is anything else introduced in C ++ 11/14 as an 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 looked through this question , but could not understand any advantages over the traditional use of function pointers. I would also like to ask if there is something wrong (not recommended) with function pointers, since I never see anyone using them. Or any other alternative gift.

+7
c ++ pointers c ++ 11 function-pointers
source share
4 answers

I would also like to ask if there is something wrong (not recommended) with function pointers, since I never see anyone using them.

Yes. Function pointers are terrible, terrible things. Firstly, they do not support generation, so you cannot use a pointer to a function that, for example, takes std::vector<T> for any T Secondly, they do not support a bound state, therefore, if at any time in the future someone wants to refer to another state, they are completely screwed up. This is especially bad since it includes this for member functions.

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

The template type is as follows:

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

The main advantages here are that it accepts any function object, including a function pointer, lambda, functor, binding result, anything, and F can have any number of function overloads with any signature, including templates, and can have any size with any bound state. So this is super-duper flexible. It is also as efficient as possible, since the compiler can embed the statement and pass the state directly in the object.

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

The main drawback here is the usual drawbacks of templates - it does not work for virtual functions and should be defined in the header.

Another approach is std::function . std::function has many similar advantages - it can be of any size, attached to any state and be any callable, but it is traded with a pair. Basically, the signature is fixed during the type definition, so you cannot have std::function<void(std::vector<T>)> for some T still unknown, and some kind of dynamic indirect / selection can also be involved ( if you can "t SBO). The advantage of this is that since std::function is a real concrete type, you can pass it the same way as with any other object, so it can be used as a parameter of a virtual function and such things.

Basically, function pointers are simply incredibly limited and cannot really do anything interesting and make the API incredibly inflexible. Their disgusting syntax is urine in the ocean, and its abbreviation with an alias pattern is fun, but pointless.

+2
source share

The question you mentioned suggests std :: function but does not emphasize (or even mention at all) its meaning in combination with std :: bind.

Your example is the simplest, but suppose you have

 std::function<void (int, int)> f ; 

A function pointer can do more or less the same thing. But suppose you need a function g (int), which is f with a second parameter associated with 0. You cannot do much with function pointers, with std :: function you can do this:

 std::function<void(int)> g = std::bind(f, _1, 0) ; 
+10
source share

I looked through this question, but could not understand the advantages over the traditional use of function pointers. Also I would like to ask if there is something wrong (not recommended) with using function pointers, since I never see anyone using them.

  • Normal "global" functions usually do not / cannot have state. Although it is not always good to have a state while traversing the functional programming paradigm, sometimes a state can come in handy when it is associated orthogonally with what has been changed (heuristic example). Moreover, functors (or function objects) have an advantage.

  • Normal functions do not compose very well (creating higher level functions of lower level functions.

  • Normal functions do not allow you to bind additional parameters on the fly.

  • Sometimes ordinary functions can act as a replacement for lambda, and vice versa, depending on the context. Often you don’t feel like writing a special function just because you have a very local / specific requirement during a "container traversal".

+3
source share

As an alternative to traditional function pointers, C ++ 11 introduced a template alias that, in combination with variadic templates, can simplify the sintax function pointer. below, an example of how to create a template function pointer:

 template <typename R, typename ...ARGS> using function = R(*)(ARGS...); 

It can be used as follows:

 void foo() { ... } int bar(int) { ... } double baz(double, float) { ... } int main() { function<void> f1 = foo; function<int, int> f2 = bar; function<double, double, float> f3 = baz; f1(); f2({}); f3({}, {}); return 0; } 

In addition, it can work with function overloads:

 void overloaded(int) { std::cout << "int version\n"; } void overloaded(double) { std::cout << "double version\n"; } int main() { function<void, int> f4 = overloaded; function<void, double> f5 = overloaded; f4({}); // int version f5({}); // double version return 0; } 

And it can be used as a pretty neat way to declare function pointer parameters:

 void callCallback(function<int, int> callback, int value) { std::cout << "Calling\n"; std::cout << "v: " << callback(value) << '\n'; std::cout << "Called\n"; } int main() { function<int, int> f2 = bar; callCallback(f2, {}); return 0; } 

This template alias can be used as an alternative to std::function , which does not have its drawbacks and advantages (a good explanation here ).

Live demo

In short, I think that a template alias in combination with variable templates is a good, good, neat and modern C ++ alternative for pointers to raw functions (this alias is still a function pointer), but std::function is good, clean, and modern C ++, and also with good benefits. Insert function pointers (or an alias) or select std::function depending on your implementation needs.

+3
source share