What is std::function in C++?
std::function is a wrapper class. So what does it wrap?
It wraps any callable.
It is perhaps the most important element in <functional> header file.
Class template std::function is a general-purpose polymorphic function wrapper. std::function is a powerful and flexible feature introduced in C++11 as part of the C++ Standard Library to provide a way to store and manipulate callable objects (functions, function pointers, functors, lambdas, etc.) in a type-safe and polymorphic manner. It is part of the <functional> header and is defined in the std
namespace.
The target of std::function is the name given to the stored callable object. A std::function is referred to as empty if it has no targets. A std::bad_function_call exception is thrown if the target of an empty std::function is invoked.
Member functions of std::function is as follows;
Let’s quickly write a sample code;
In the main function, it creates a std::function object “f” that can hold a function taking an int argument and returning an int. It initializes “f” with the “func” function. It calls f(10), which invokes the stored “func” function with the argument 10, and then prints the result, which is 20.
I have said before that std::function can be used with all callable objects. So we can assign lambda expression to object “f”.
As seen in the example above, We can assign a lambda expression to a std::function object. When we used the “f” object again with the call operator, we saw that it called the lambda.
We can assign anything callable to object “f”. So we can also assign the call operator of a class as follows;
In the main function, we create a std::function<int(int)> object “f” and initialize it with a lambda function that squares its input and prints a message. We create an instance of the “Ceng” class named “ceng” with “_x” set to 25. We assign the “ceng” object to the std::function object “f”. This demonstrates that std::function can store not only plain functions and lambda functions but also objects with operator() overloads.
So as a result, std::function can wrap all callables with the same return type and parameter type.
So it’s a very good alternative to function pointers!!!
Let’s examine it with an example.
Defining an alias “using” using is a convenient way to simplify the code and make it more readable, especially when you are working with complex types like std::function. So we defined a using statement.
funcCaller() takes a func object “f” and an integer value. Inside funcCaller, it calls the provided func object “f” with the integer “val” and returns the result. It also prints a message indicating that funcCaller was called. It calls funcCaller() with a lambda function as the first argument. This lambda function captures temp and multiplies it by 50.
The funcCaller() function above takes std::function in its parameter. If this were a function pointer, we could only send one function as a parameter, but now we can easily send any callable such as lambda.
So most of the time we can use it instead of function pointers. It is even safer than function pointers.
Yes, This is great :)
Remember when you use function pointers, you had to do a null check.
If you call a function pointer that is null, the system may crash.
You can check whether std::function is empty or not with the bool operator.
While “f” is empty;
While “f” is not empty;
If a call is made while empty, it throws an exception.
Yes, as you can see, bad_function_call throws an exception.