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 */
posted @ 2020-03-01 01:42  kaizenly  阅读(1771)  评论(0编辑  收藏  举报
打赏