前言
std::function 作为标准库提供的函数指针,使用起来还是比较方便的,不过在使用过程中有一些需要注意的细节,这里做一个简单的记录。
基本使用
- 头文件:
#include <functional>
- 语法:
std::function<return_type(args_type)>
#include <iostream>
#include <functional>
using namespace std;
void func(int i, int g) {
int count = 10;
while (count > 0) {
cout << "func: " << i << " " << g<< endl;
sleep(1);
}
}
int main() {
std::function<void(int,int)> job = func;
job(10,10);
return 0;
}
- 其中return_type 是函数指针的返回值类型,像上面案例中
函数的func
void
类型。
其中args_type 是函数指针的参数类型,有多个函数参数,就可以有多个数据类型。
函数指针作为参数 需要注意的事项
- 如果直接使用一个已经存在的函数来进行传参数,则需要声明调用者函数参数的
std::function
为const类型。
具体也就是类似 我们使用"dfafasd" 初始化一个
引用类型的字符串参数。这个时候因为是引用传递,而传递的时候却没有用变量,而是使用了一个常量,则需要保证这个函数的声明参数中有一个const ,才能将常量数据的地址正确得放在常量区域。即 正确的声明应该如 void test_string(std::string& res)
同理,std::function在使用一个已经存在的函数初始化的时候类似。如下代码是正确的:void test_string(const std::string& res)
void stl_func(const std::function<void(int, int)>& job, int num, int g) {
job(num, g);
}
void func(int i, int g) {
int count = 10;
while (count > 0) {
cout << "func: " << i << " " << g<< endl;
sleep(1);
}
}
int main() {
stl_func(func,10,1);
return 0;
}
candidate function not viable: no know conversion from 'void()' to 'std::function<void(int,int)> &'
for 1'st argument.
- 使用一个函数指针变量 来进行参数传递,则不需要调用者函数参数的
std::function
为const。
还是如上代码,修改之后:
void stl_func(std::function<void(int, int)>& job, int num, int g) {
job(num, g);
}
void func(int i, int g) {
int count = 10;
while (count > 0) {
cout << "func: " << i << " " << g<< endl;
sleep(1);
}
}
int main() {
std::function<void(int, int)> job = func;
// 使用函数指针 变量进行传递就没有问题
stl_func(job, 10, 10);
return 0;
}
- 在类的成员函数之间 将 std::function 作为参数传递时需要注意 如下使用过程:
#include <iostream>
#include <functional>
using namespace std;
void stl_func_bak(std::function<void()>& job) {
job();
}
class Cb {
public:
static void cb_func() {
while(1) {
cout << "cb_func: " << 10 << endl;
usleep(100000);
}
}
void stl_cb_func() {
// 函数成员作为传递的参数需要确保编译期间就能够分配好函数内存
// 函数栈需要在编译期间获得内存,所以需要声明 cb_func 成员函数 为 static
stl_func_bak(Cb::cb_func);
}
};
int main() {
Cb* cb = new Cb();
cb->stl_cb_func();
return 0;
}