C++11 std::function函數包裝器

【1】std::function簡介ios

std::function是一個函數包裝器模板,最先來自boost庫,對應其boost::function函數包裝器。函數

一個std::function類型對象實例可包裝如下可調用元素類型等等:spa

(1)函數指針

(2)函數指針code

(3)類成員函數指針對象

(4)任意類型的函數對象(例如:定義了operator()操做符重載的類型)。blog

std::function對象可被拷貝和轉移,而且可使用指定的調用特徵來直接調用目標元素。ci

當std::function對象未包裹任何實際的可調用元素,調用該std::function對象將拋出std::bad_function_call異常。string

【2】std::funciton使用it

 1 #include <iostream>
 2 #include <functional>
 3 using namespace std;  4 
 5 int subtract(int m, int n)  6 {  7     return (m - n);  8 }  9 
 10 template <class T>
 11 T g_sub(T m, T n)  12 {  13     return (m - n);  14 }  15 
 16 auto g_Lambda = [](int m, int n)  17 {  18     return (m - n);  19 }; // 注意:匿名函數此處有分號
 20 
 21 struct Sub  22 {  23     int operator()(int m, int n)  24  {  25         return (m - n);  26  }  27 };  28 
 29 template <class T>
 30 struct SubTemp  31 {  32     T operator()(T m, T n)  33  {  34         return (m - n);  35  }  36 };  37 
 38 class SubOper  39 {  40 public:  41     static int st_sub(int m, int n)  42  {  43         return (m - n);  44  }  45 
 46     template <class T>
 47     static T temp_sub(T m, T n)  48  {  49         return (m - n);  50  }  51 
 52     double result(double m, double n)  53  {  54         return (m - n);  55  }  56 
 57     double const_result(double m, double n) const
 58  {  59         return (m - n);  60  }  61 };  62 
 63 int main()  64 {  65     // 舊式寫法
 66     typedef int (*pFunc) (int, int);  67     pFunc oldFunc = subtract;  68     cout << "Test old style :: " << (*oldFunc)(9, 10) << endl; // -1  69 
 70     // [0] 包裝函數指針對象
 71     std::function<int(int, int)> from_pFunc = oldFunc;  72     cout << "Test0 :: " << from_pFunc(10, 10) << endl; // 0  73 
 74     // [1]包裝普通函數
 75     std::function<int(int, int)> newFunc = subtract;  76     cout << "Test1 :: " << newFunc(11, 10) << endl;   // 1  77 
 78     // [2]包裝模板函數
 79     std::function<int(int, int)> tempFunc = g_sub<int>;  80     cout << "Test2 :: " << tempFunc(12, 10) << endl;   // 2  81 
 82     // [3]包裝Lambda函數
 83     std::function<int(int, int)> lambdaFunc = g_Lambda;  84     cout << "Test3 :: " << lambdaFunc(13, 10) << endl;   // 3  85 
 86     // [4]包裝仿函數
 87     std::function<int(int, int)> objFunc = Sub();  88     cout << "Test4 :: " << objFunc(14, 10) << endl;     // 4  89 
 90     // [5]包裝模板函數對象
 91     std::function<int(int, int)> tempFuncObj = SubTemp<int>();  92     cout << "Test5 :: " << tempFuncObj(15, 10) << endl;     // 5  93 
 94     // [6] 類靜態函數
 95     std::function<int(int, int)> stFunc = &SubOper::st_sub;  96     cout << "Test6 :: " << stFunc(16, 10) << endl;   // 6  97 
 98     // [7] 類靜態模板函數
 99     std::function<int(int, int)> tempSTFunc = &SubOper::temp_sub<int>; 100     cout << "Test7 :: " << tempSTFunc(17, 10) << endl;  // 7 101 
102     // [8] 類普通函數(普通函數綁定須要依賴類對象)
103  SubOper subOperObject; 104 
105     // [8.1] 使用bind,將類對象地址綁定上
106     std::function<double(double, double)> resultFunc = std::bind(&SubOper::result, &subOperObject, placeholders::_1, placeholders::_2); 107     cout << "Test8.1 :: " << resultFunc(18.2, 10.1) << endl;   // 8.1 108 
109     // [8.2] 不使用bind
110     std::function<double(SubOper &, double, double)> resultFunc2 = &SubOper::result; 111     cout << "Test8.2 :: " << resultFunc2(subOperObject, 18.3, 10.1) << endl;   // 8.2 112 
113     // [8.3] const
114     std::function<double(SubOper &, double, double)> const_resultFunc2 = &SubOper::const_result; 115     cout << "Test8.3 :: " << const_resultFunc2(subOperObject, 18.4, 10.1) << endl;   // 8.3 116 
117     // [8.4] 常量對象
118     const SubOper subOperConst; 119     std::function<double(const SubOper &, double, double)> const_Func2 = &SubOper::const_result; 120     cout << "Test8.4 :: " << const_Func2(subOperConst, 18.5, 10.1) << endl;   // 8.4 121 
122     // [9] 應用示例(爲了解耦)
123     class TestA 124  { 125     public: 126         bool destoryByName(const std::string& name) 127  { 128             return doDestoryByName(name); 129  } 130 
131     public: 132         std::function<bool(const std::string&)> destory_handler; 133 
134     private: 135         bool doDestoryByName(std::string name) 136  { 137             return destory_handler(name); 138  } 139  }; 140 
141     class TestB 142  { 143     public: 144         bool destory(const std::string& name) 145  { 146             cout << "Test9 :: Call TestB destory | name : " << name << endl; 147             return true; 148  }; 149  }; 150 
151  TestB objB; 152  TestA objA; 153     objA.destory_handler = [&](const std::string & name)->bool { 154         // 摧毀操做
155         return objB.destory(name); 156  }; 157     objB.destory("kaizen"); 158 
159     // [10] 爲空時運行時異常
160     std::function<int(int, int)> dealWithFunc; 161 
162     try
163  { 164         if (nullptr == dealWithFunc) 165  { 166             throw runtime_error("std::bad_function_call");   //拋出異常
167  } 168         else
169  { 170             dealWithFunc(100, 10); 171  } 172  } 173     catch (exception e) 174  { 175         cout << "Test10 :: " << e.what() << endl;   // 捕獲異常,而後程序結束
176  } 177 
178     system("pause"); 179 } 180 
181 /* rusult 182 Test old style :: -1 183 Test0 :: 0 184 Test1 :: 1 185 Test2 :: 2 186 Test3 :: 3 187 Test4 :: 4 188 Test5 :: 5 189 Test6 :: 6 190 Test7 :: 7 191 Test8.1 :: 8.1 192 Test8.2 :: 8.2 193 Test8.3 :: 8.3 194 Test8.4 :: 8.4 195 Test9 :: Call TestB destory | name : kaizen 196 Test10 :: std::bad_function_call 197 請按任意鍵繼續. . . 198 */

 

good good study, day day up.

順序 選擇 循環 總結

相關文章
相關標籤/搜索