Notes on the fifth edition of c++primer: function pointer

p221

The type of a function is determined by its return type and formal parameter type, regardless of the function name. Take chestnuts for example:

bool lengthCompare(const string &,const string &)

The type of this function is bool (const string &, const string &). To declare a pointer that can point to the function, simply replace the function with a pointer:

//pf refers to a function whose parameters are references to two const string s. When returning, it is of type bool
bool (*pf)(const string &,const string &);

*Parentheses at both ends of pf are essential. If you do not write this pair of parentheses, pf is a function that returns a bool pointer.

Using function pointers

When we use a function as a value, the function is automatically converted to a pointer. Take chestnuts for example:

pf=lengthCompare;//pf points to the lengthCompare function
pf=&lengthCompare;//Equivalent assignment statement, the address character is optional

In addition, we can call the function directly with the pointer pointing to the function without dereferencing the pointer in advance:

bool b1=pf("hello","good");
bool b2=(*pf)("hello","good");
bool b3=lengthCompare("hello","good");

There are no conversion rules between pointers to different function types. But as usual, we can assign a nullptr or an integer constant expression of 0 to the function pointer, indicating that the pointer does not point to any function.

Pointer to overloaded function

When we use overloaded functions, the context must clearly define which function should be selected. If a pointer to an overloaded function is defined:

void ff(int*);
void ff(unsigned int);
void (*pf1)(unsigned int)=ff;//pf1 points to ff(unsigned int)
void (*pf2)(int)=ff;//Error: no ff matches the parameter list
void (*pf3)(int*)=ff;//Error: return types of ff and pf3 do not match

Function pointer parameter

Like arrays, although formal parameters of function types cannot be defined, they can be pointers to functions. At this time, the formal parameter looks like a function type, but it is actually used as a pointer:

//The third parameter is the function type, which is automatically converted to a pointer to the function
void useBigger(const string&s1,vonst string&s2,
              bool pf(const string&,const string&));
//Display declaration: displays a pointer that converts a formal parameter to a function
void useBigger(const string&s1,vonst string&s2,
              bool (*pf)(const string&,const string&));

We can directly use the function as an argument, which will be automatically converted into a pointer.

useBigger(s1,s2,lengthCompare);

We can also use type aliases to simplify code that uses function pointers:

//Func and Func2 are function types
typedef bool Func(const string&,const string&);
typedef decltype(lengthCompare) Func2;
//FuncP and FuncP2 are pointers to functions
typedef bool (*FuncP)(const string&,const string&);
typedef decltype(lengthCompare) *FuncP2;

The equivalent declaration of useBigger with alias is as follows:

void useBigger(const string&,const string&,Func);
void useBigger(const string&,const string&,FuncP2);

Returns a pointer to a function

Similar to arrays, although you cannot return a function, you can return a pointer to the function type. However, we must write the return type as a pointer, and the compiler will not automatically treat the function return type as the corresponding pointer type. As usual, the easiest way to declare a function that returns a function pointer is to use a type alias:

using F=int(int*,int);//F is a function type, not a pointer
using PF=int(*)(int*,int);//PF is a pointer type

Among them, we use type alias to define F as function type and PF as pointer to function type. It must always be noted that unlike the formal parameters of function types, the return type will not be automatically converted into a pointer. We must specify the return type as a pointer:

PF f1(int);//Correct: PF is the pointer to the function, and f1 returns the pointer to the function
F f2(int);//Error: F is a function type, f1 cannot return a function
F *f3(int);//Correct: the specified return type is a pointer to the function

Of course, we can also directly declare f1 in the following form:

int (*f1(int))(int*,int);

There are also ways to set the tail return type:

auto f1(int)->int(*)(int*,int);

Keywords: C++ Back-end

Added by lizzyd on Wed, 02 Feb 2022 07:59:05 +0200