C++11 std::function函数包装器
【1】std::function简介
std::function是一个函数包装器模板,最早来自boost库,对应其boost::function函数包装器。
一个std::function类型对象实例可包装以下可调用元素类型如下:
(1)函数
(2)函数指针
(3)类成员函数指针
(4)任意类型的函数对象(例如:定义了operator()操作符重载的类型)。
std::function对象可被拷贝和转移,并且可以使用指定的调用特征来直接调用目标元素。
当std::function对象未包裹任何实际的可调用元素,调用该std::function对象将抛出std::bad_function_call异常。
【2】std::funciton使用
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 objA.destoryByName("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 // [11] 作为形参类型使用 179 class Print 180 { 181 public: 182 void doPrint(std::string content) 183 { 184 cout << "Test11 :: Call Print Class doPrint : " << content << endl; 185 } 186 }; 187 188 class Person 189 { 190 public: 191 Person(std::string name = {}) : m_name(name) 192 { } 193 194 void show(std::function<void(std::string)> printFunc) 195 { 196 printFunc(m_name); 197 } 198 private: 199 std::string m_name; 200 }; 201 202 // error 203 Person oObj1{ "hello" }; 204 //p1.show(&Print::doPrint); // 无法将参数 1 从“void (__cdecl main::Print::* )(std::string)”转换为“std::function<void (std::string)>” 205 206 // 方式一: 207 std::function<void(std::string)> printFunc1 = [](std::string str) { 208 Print{}.doPrint(str); 209 }; 210 Person{"C++"}.show(printFunc1); 211 212 // 方式二: 213 Print oPrint; 214 std::function<void(std::string)> printFunc2 = std::bind(&Print::doPrint, &oPrint, placeholders::_1); 215 Person{"Python"}.show(printFunc2); 216 217 system("pause"); 218 } 219 220 /* result 221 Test old style :: -1 222 Test0 :: 0 223 Test1 :: 1 224 Test2 :: 2 225 Test3 :: 3 226 Test4 :: 4 227 Test5 :: 5 228 Test6 :: 6 229 Test7 :: 7 230 Test8.1 :: 8.1 231 Test8.2 :: 8.2 232 Test8.3 :: 8.3 233 Test8.4 :: 8.4 234 Test9 :: Call TestB destory | name : kaizen 235 Test10 :: std::bad_function_call 236 Test11 :: Call Print Class doPrint : C++ 237 Test11 :: Call Print Class doPrint : Python 238 请按任意键继续. . . 239 */