简介
函数指针指向的是函数而非对象,与其他指针一样,函数指针指向某种特定类型。函数的类型由它的返回类型和形参类型共同决定,与函数名无关。
bool lengthCompare(const string &, const string &);// pf是一个未初始化的函数指针: 参数是两个const string的引用, 返回值是bool类型bool (*pf) (const string &, const string &);
把函数名作为一个值时, 该函数自动转换成指针:
// pf指向名为lengthCompare的函数pf = lengthCompare;// 等价写法pf = &lengthCompare;
我们可以使用函数指针调用该函数:
// 等价的三种写法bool b1 = pf("tomo", "cat");bool b2 = (*pf)("tomo", "cat");bool b3 = lengthCompare("tomo", "cat");
函数指针形参
虽然不能定义函数类型的形参,但是形参可以是指向函数的指针:
// 第三个参数是函数类型, 它会自动转换成函数指针void useBigger(const string &s1, const string &s2,bool pf(const string &, const string &));// 等价声明: 显式将形参定义成函数指针void useBigger(const string &s1, const string &s2,bool (*pf) (const string &, const string &));
我们可以使用类型别名和decltype来简化使用了函数指针的代码:
Tips:decltype返回函数类型,此时不会将函数类型自动转换成指针类型,只有在结果前面加上
*才能得到函数指针。
// Func1和Func2是函数类型typedef bool Func1(const string&, const string&);typedef decltype(lengthCompare) Func2;// FuncP1和FuncP2是函数指针类型typedef bool(*FuncP1)(const string&, const string&);typedef decltype(lengthCompare) *FuncP2;// 使用类型别名简化useBigger函数的声明void useBigger(const string&, const string&, Func1);void useBigger(const string&, const string&, Func2);void useBigger(const string&, const string&, FuncP1);void useBigger(const string&, const string&, FuncP2);
返回指向函数的指针
1. 类型别名using简化返回函数指针的函数声明
一般情况下直接声明返回函数指针的函数比较复杂:
// foo参数为int, 返回值是int(*)(int*, int)的函数指针int (*foo(int))(int*, int);
新标准下我们可以使用using关键字定义类型别名:
// F是函数类型而非函数指针类型using F = int(int*, int);// PF是函数指针类型using PF = int(*)(int*, int);
有了类型别名我们可以将foo函数重新声明为:
// foo接收int类型作为参数, 返回PF的函数指针PF foo(int);// 等价写法F *foo(int);
2. 尾置返回类型
前面提到的foo函数还有另外一种声明方式:
auto foo(int) -> int(*)(int* int);
