GitLab now enforces expiry dates on tokens that originally had no set expiration date. Those tokens were given an expiration date of one year later. Please review your personal access tokens, project access tokens, and group access tokens to ensure you are aware of upcoming expirations. Administrators of GitLab can find more information on how to identify and mitigate interruption in our documentation.
What we pass to ```std::set```'s constructor is a **function pointer** of type
What we pass to ```std::set```'s constructor is a **function pointer** of type
bool (*) ( const myPair&, const myPair& )
bool (*) ( const myPair&, const myPair& )
%% Cell type:markdown id:dc79e822 tags:
%% Cell type:markdown id:dc79e822 tags:
***
***
- This way to work with functions is something that C++ inherited from C.
- This way to work with functions is something that C++ inherited from C.
- Not only in the STL, but also in scientific programming we often have the case that we implement something, but want to leave some details to the user:
- Not only in the STL, but also in scientific programming we often have the case that we implement something, but want to leave some details to the user:
- Consider e.g. implementing an algorithm to approximate the integral
- Consider e.g. implementing an algorithm to approximate the integral
$$I = \int_a^b f(x)\, dx$$
$$I = \int_a^b f(x)\, dx$$
- When we code that we would like to leave the details of the integrand to be specified flexibly by the user.
- When we code that we would like to leave the details of the integrand to be specified flexibly by the user.
- As with std::set we can let the user provide a function that we then call inside our code.
- As with std::set we can let the user provide a function that we then call inside our code.
- This is known as a **callback**.
- This is known as a **callback**.
- The main downside to using function (pointers) in this approach is that a free function is **stateless**. In order to influence its behaviour we have to pass arguments through its interface. That does not work nicely with the callback idea.
- The main downside to using function (pointers) in this approach is that a free function is **stateless**. In order to influence its behaviour we have to pass arguments through its interface. That does not work nicely with the callback idea.
- Note: We can add *state* to a function by making some of its local variables ```static```. See the ```accumulate``` examples.
- Note: We can add *state* to a function by making some of its local variables ```static```. See the ```accumulate``` examples.
- However, a function is a global entity. Thus, there can always only be one state for it.
- However, a function is a global entity. Thus, there can always only be one state for it.
%% Cell type:markdown id:9ce08962 tags:
%% Cell type:markdown id:9ce08962 tags:
#### Functors
#### Functors
In C++ we can as one alternative use a **function object**, a.k.a. **functor**. This is an object of a class that overloads the function call operator ```operator()```.
In C++ we can as one alternative use a **function object**, a.k.a. **functor**. This is an object of a class that overloads the function call operator ```operator()```.
##### **Example 1:**
##### **Example 1:**
%% Cell type:code id:9bf146ec tags:
%% Cell type:code id:9bf146ec tags:
``` C++14
``` C++14
#include <iostream>
#include <iostream>
class greeter{
class greeter{
public:
public:
void operator() ( const std::string& str ) {
void operator() ( const std::string& str ) {
std::cout << "Greetings " << str << std::endl;
std::cout << "Greetings " << str << std::endl;
}
}
};
};
```
```
%% Cell type:code id:b13aa200 tags:
%% Cell type:code id:b13aa200 tags:
``` C++14
``` C++14
int main() {
int main() {
greeter hello;
greeter hello;
hello( "Class" );
hello( "Class" );
}
}
```
```
%% Cell type:code id:f7a3701a tags:
%% Cell type:code id:f7a3701a tags:
``` C++14
``` C++14
main();
main();
```
```
%% Output
%% Output
Greetings Class
Greetings Class
%% Cell type:markdown id:58a187c4 tags:
%% Cell type:markdown id:58a187c4 tags:
***
***
Now that was a simple functor and did only demonstrate **how** it works and not **why** that approach can be advantageous.
Now that was a simple functor and did only demonstrate **how** it works and not **why** that approach can be advantageous.
##### **Example 2:**
##### **Example 2:**
In our second example we will use a stateful functor that allows to perform different binary operations. The type of operation will be passed via its constructor.
In our second example we will use a stateful functor that allows to perform different binary operations. The type of operation will be passed via its constructor.
%% Cell type:code id:8c0f30c5 tags:
%% Cell type:code id:8c0f30c5 tags:
``` C++14
``` C++14
#include <iostream>
#include <iostream>
class BinaryOperator {
class BinaryOperator {
public:
public:
typedef enum { ADD, MULT } type;
typedef enum { ADD, MULT } type;
BinaryOperator() = delete;
BinaryOperator() = delete;
BinaryOperator( BinaryOperator::type op ) : whatToDo( op ) {};
BinaryOperator( BinaryOperator::type op ) : whatToDo( op ) {};
> Class template std::function is a general-purpose polymorphic function wrapper. Instances of std::function can store, copy, and invoke any CopyConstructible Callable target -- functions, lambda expressions, bind expressions, or other function objects, as well as pointers to member functions and pointers to data members.
> Class template std::function is a general-purpose polymorphic function wrapper. Instances of std::function can store, copy, and invoke any CopyConstructible Callable target -- functions, lambda expressions, bind expressions, or other function objects, as well as pointers to member functions and pointers to data members.
>
>
> The stored callable object is called the target of std::function. If a std::function contains no target, it is called empty. Invoking the target of an empty std::function results in std::bad_function_call exception being thrown.
> The stored callable object is called the target of std::function. If a std::function contains no target, it is called empty. Invoking the target of an empty std::function results in std::bad_function_call exception being thrown.
The functionality of ```std::function``` is quite useful especially in combination with lambda functions (see below).
The functionality of ```std::function``` is quite useful especially in combination with lambda functions (see below).