天天看点

C++ std::function<void(int)> 和 std::function<void()> 作为函数参数的注意事项

前言

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 是函数指针的参数类型,有多个函数参数,就可以有多个数据类型。

函数指针作为参数 需要注意的事项

  1. 如果直接使用一个已经存在的函数来进行传参数,则需要声明调用者函数参数的​

    ​std::function​

    ​ 为const类型。

    具体也就是类似 我们使用"dfafasd" 初始化一个 ​

    ​void test_string(std::string& res)​

    ​ 引用类型的字符串参数。这个时候因为是引用传递,而传递的时候却没有用变量,而是使用了一个常量,则需要保证这个函数的声明参数中有一个const ,才能将常量数据的地址正确得放在常量区域。即 正确的声明应该如 ​

    ​void test_string(const std::string& res)​

    ​同理,std::function在使用一个已经存在的函数初始化的时候类似。如下代码是正确的:
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.      
  1. 使用一个函数指针变量 来进行参数传递,则不需要调用者函数参数的 ​

    ​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;
}      
  1. 在类的成员函数之间 将 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;
}