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);