/* stl::bind 使用 */ #include <iostream> #include <string> #include <functional> /* 知識補充: std::bind綁定器 將函數、成員函數和閉包轉成function函數對象 將多元(n>1)函數轉成一元函數或者(n-1)元函數。 bind()接受一個函數(或者函數對象,或者任何你可以通過"(...)"符號調用的事物),生成一個其有某一個或多個函數參數被“綁定”或重新組織的函數對象。 顧名思義,bind()函數的意義就像它的函數名一樣,是用來綁定函數調用的某些參數的。 bind的返回值是可調用實體,可以直接賦給std::function對象 */ /* 學生類 */ class Student { public: //構造函數 Student(unsigned int id, const std::string &name) :_id(id), _name(name) { } //析構函數 ~Student() { } public: //調用 int test() { const std::string msg = "hello world ."; //綁定成員函數 auto func = std::bind(&Student::show, this, std::placeholders::_1); //執行方法 func(msg); return 0; } private: //展示學生信息 void show(const std::string &msg) { printf(" student info : id [%u] , name [%s] , msg [%s] .\n", this->_id, this->_name.c_str(), msg.c_str()); } private: unsigned int _id; std::string _name; }; void test1() { /* 知識點1: std::bind 綁定成員函數,並且將多元函數 轉成 一元函數 */ Student stu(12, "tom"); stu.test(); } //全局函數 static void see(int i, char c, double d) { printf("===int[%d]====char[%c]===double[%lf]==\n", i, c, d); } void test2() { /* 知識點2: std::bind 綁定全局函數,並且將多元函數 轉成 一元函數 */ //定義函數指針 void(*pFunc)(int, char, double) = see; //綁定函數,並且部分賦值參數 auto b_func = std::bind(pFunc, std::placeholders::_1, 'c', 1.2); b_func(10); } void test3() { /* 知識點3: std::bind 調整參數順序 */ //定義函數指針 void(*pFunc)(int, char, double) = see; //綁定函數,並且部分賦值參數 auto b_func = std::bind(pFunc, std::placeholders::_2, 'h', std::placeholders::_1); /* 設計說明: std::placeholders::_1 表示的是b_func的第一個參數 std::placeholders::_2 表示的是b_func的第二個參數 */ b_func(1.4, 5); } int b_same(int x, int y) { printf("---b_same1--x[%d]---y[%d]------\n", x, y); return 0; } void b_same(double x, double y) { printf("---b_same2--x[%lf]---y[%lf]------\n", x, y); } void test4() { /* 知識點4: std::bind 綁定重載函數,需要顯式地指定函數簽名 */ //綁定函數 std::function<void(double, double)> b_func = std::bind((void(*)(double, double))b_same, std::placeholders::_1, std::placeholders::_2); /* 注意: std::function 的模板參數是 函數簽名,而非函數指針 */ b_func(3.3, 4.4); } int main() { //printf("-----test1()-------\n"); //test1(); //printf("-----test2()-------\n"); //test2(); //printf("-----test3()-------\n"); //test3(); printf("-----test4()-------\n"); test4(); return 0; }
/* std::function初始化注意點 */ #include <iostream> #include <string> #include <functional> using namespace std; typedef std::function<void(int)> TestCallback; typedef void(*test_fn)(int); void test() { //std::function 初始化方式一 TestCallback cb1 = NULL; //std::function 初始化方式二 TestCallback cb2 = TestCallback(); if (cb1) { printf("-----Callback1 not empty .------\n"); } if (cb2) { printf("-----Callback2 not empty .------\n"); } //std::function 錯誤初始化 強調 cb3如果不初始化,值將是不確定 TestCallback cb3; test_fn fn = NULL; cb3 = std::bind(fn, std::placeholders::_1); if (cb3) { /* 說明: 此時 cb3 實際上並沒有方法實體,但是 if (cb3) 判斷卻是不為空,如果調用 cb3() 就會導致程序崩潰 因此在使用std::bind()方法之前一定要判斷綁定的函數是否為 NULL */ printf("-----Callback3 not empty .------\n"); } } int main() { test(); getchar(); return 0; }