天天看點

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