753 字
4 分钟
C++杂记 - 3(四):函数类型、函数指针与函数引用
2022-09-06

函数类型,函数指针类型和函数指针的区别#

  • 函数指针指向的是函数而非对象。和其他指针类型一样,函数指针指向某种特定类型。
  • 函数类型由它的返回值和参数类型决定,与函数名无关。
  • 函数指针类型就是函数指针的类型。
bool func(const string& a, const string& b);

上述函数类型是:bool (const string &, const string &); 函数指针类型是:bool (*)(const string &, const string &);

我们提到过,函数名称在使用时会被自动转换为函数指针。也就是:

fptr_name = func
等价于
fptr_name = &func
bool Func(const string&, const string&); // Func是函数类型;
bool (*FuncP)(const string&, const string&); // FuncP是函数指针类型;
typedef decltype(Func) Func2; // Func2是函数类型;
typedef decltype(FuncP) *Func2P; // Func2P是函数指针类型;

注意decltype(Func)返回的是函数类型,而不是函数指针类型;

  • 下面两个声明语句是同一个函数,因为编译器会自动的将Functoin_Type 转换成函数指针类型。
void test(int a, int b, Functoin_Type fn);
void test(int a, int b, Funcion_Pointer fn);

测试:

using Functoin_Type = int(float,int); //函数类型
using Funcion_Pointer = int(*)(float, int); //函数指针类型
void callback1(Functoin_Type callable){ //函数类型当形参。自动转换
callable(1.2f,2);
}
void callback2(Funcion_Pointer callable){ //函数指针当形参。
callable(1.2f,2);
}
int testsor(float b, int c){
cout << b << endl;
cout << c << endl;
cout <<"success" << endl;
return 1;
}
int main(){
// test<int(float, int)> obj;
// obj.construct(testsor, 2.5f, 234);
callback1(testsor); //效果一致
callback2(testsor); //效果一致
return 0;
}
  • 做为返回值时,由于返回的必须是函数指针类型而非函数类型,所以
Functoin_Type ret1(){
//错误。返回的是函数类型
}
Funcion_Pointer ret2(){
//正确。返回的是函数指针类型。
}

函数类型有一个非常特殊的地方:不能使用函数类型声明变量,但是可以把它当做函数的形参(编译器会自动转换)

https://zh.cppreference.com/w/cpp/language/function

形参列表部分:

…

形参列表中的每个函数形参的类型根据下列规则确定:

…

  1. 如果类型是函数类型 F,那么它被替换成类型F 的指针”

…

Functoin_Type f = testsor; //错误 不可使用函数类型声明变量。
Funcion_Pointer f = testsor; //正确
  • 成员函数指针类型
class obj{
public:
bool func(int, int){
std::cout <<"called" << endl;
}
};
cout <<is_same<bool(obj::*)(int, int), decltype(&obj::func)>::value << endl; //true
  • 注意,函数指针类型是一个整体。不能把他们分开。比如函数指针bool (*pf)(int) 的类型是 bool (*)(int)。在模板接受一个参数的时候,不能把返回值类型bool扒下来。
  • 当然了,如果想,也可以利用成员函数指针类型的方法把他们分开。
template<typename R, typename T, typename... Args>
void f(R(T::*pf)(Args... args)){
std::puts(__PRETTY_FUNCTION__);
}
//void f(R (T::*)(Args ...)) [with R = bool; T = obj; Args = {int, int}]

https://www.jianshu.com/p/6ecfd541ec04

https://stackoverflow.com/questions/17446220/c-function-types

https://stackoverflow.com/questions/13233213/can-a-function-type-be-a-class-template-parameter

https://stackoverflow.com/questions/72926596/type-deduction-for-a-member-function-pointer

函数引用#

和函数指针,函数名没啥区别。主要遇到的地方是杂记4中的decltype的函数名做为表达式的部分。剩下的看下面的链接即可。

https://stackoverflow.com/questions/19200513/function-pointer-vs-function-reference

C++杂记 - 3(四):函数类型、函数指针与函数引用
https://sterben-01.github.io/posts/杂记3-4/
作者
Sterben_01
发布于
2022-09-06
许可协议
CC BY-NC-SA 4.0