A function pointer is a variable that holds the address of a function rather than a data value that we saw in pointers.

When we declare (or define) a function and refer that function later in the code, we implicitly using a function pointer.

Creating a function pointer

We can create a function pointer to point a function as follows:

Syntax

return_type (*pointer_name)([arg...] if any);

For example,

int add(int a, int b)
{
    return a + b;
}
 
int (*fptr)(int, int);
 
fptr = &add; // explicitly converting to address
 
// or 
 
fptr = add; // implicitly converting to address (recommended)

We can initialize the function pointer while defining it:

int (*fptr)(int, int){add}; // implicitly converting to address

Invoking a function using function pointer

Invoking a function using function pointer can be done in two ways:

  1. Explicit dereferencing the pointer and calling the function.
std::cout << (*fptr)(1, 2);
  1. Directly calling the pointer variable.
std::cout << fptr(1, 2);

This looks same as calling a normal function. Compiler implicitly does the dereferencing of the pointer. This is the recommended and cleaner approach.

Function pointer with default arguments

Invoking a function using function pointer does not allow us to use default arguments. For example, following would fail:

int add(int a, int b = 1)
{
    return a + b;
}
 
int (*fptr)(int, int){add};
 
fptr(1); // would fail

When compiler encounters a function (not function pointer) call with default arguments, compiler rewrites the call with the default arguments passed in to the call. This conversion happens at compile time.

However, in case of function pointer, the function resolution happens at run time so the default argument conversion does not work here.

References

  1. https://www.learncpp.com/cpp-tutorial/function-pointers/