zoukankan      html  css  js  c++  java
  • 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     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.

    顺序 选择 循环 总结

  • 相关阅读:
    Map
    input输入框文字提示IE兼容
    Linux下实现获取远程机器文件
    ssl_error_rx_record_too_long
    Linux下访问网站
    Linux安装Jdk1.7
    bootstrap左右圆角按钮-适配手机页面
    jQuery使用load方法加载其他文档内容
    Js操作DOM小练习_01
    BootstrapValidator验证表单用法
  • 原文地址:https://www.cnblogs.com/Braveliu/p/12387684.html
Copyright © 2011-2022 走看看