zoukankan      html  css  js  c++  java
  • C++11 function使用

    function是一组函数对象包装类的模板,实现了一个泛型的回调机制。

    引入头文件

    #include <functional>
    using namespace std;
    using namespace std::placeholders;  //bind的时候会用`

    参考:http://www.cnblogs.com/hujian/archive/2012/12/07/2807605.html

    fuction  bind:http://blog.csdn.net/fjb2080/article/details/7527715

    我们可以调用的对象有很多,比如普通函数、函数指针、lanmbda表达式、函数对象和类的成员函数等。

    不管采用哪种方式,主要调用形式一样(返回值类型、传递给调用的实参类型),我们就可以使用同一种形式来调用。

    这个时候就可以用到function模板,它给予我们在调用的方式上更大的弹性。

    请看一下三种不同的函数定义:

    [cpp] view plain copy
     
     print?
    1. int add(int a, int b){  
    2.     return a+b;  
    3. }  
    4. auto mod=[](int a, int b){return a%b;};  
    5. struct divide{  
    6.     int operator()(int m, int n){  
    7.         return m/n;  
    8.     }  
    9. };  

    这三种都可以使用同一种调用形式,int(int, int),调用方式如下:

    [cpp] view plain copy
     
     print?
    1. function<int(int,int)> func1= add;  
    2. function<int(int,int)> func2= divide();  
    3. function<int(int,int)> func3= mod;  
    4. cout<<func1(5, 6)<<endl;  
    5. cout<<func2(5, 6)<<endl;  
    6. cout<<func3(5, 6)<<endl;  


    学会了使用function,可以继续如下进行抽象定义,不同类型采用相同的调用方法:

    [cpp] view plain copy
     
     print?
    1. map<string,function<int(int, int)>> funs =  
    2. {  
    3.     {"+", add},  
    4.     {"-", std::minus<int>()},//标准库的函数,参数为两个整数,可以参考前一篇博客  
    5.     {"/", divide()},//类成员函数  
    6.     {"*", [](int i,int j){return i*j;}},//lambda表达式  
    7.     {"%", mod},  
    8. };  
    9. funs["+"](4,6);  


    以上就是function的简单使用。下面是从另一篇博客转载的,使用function的引用来保存函数对象。考虑下面代码:

    [cpp] view plain copy
     
     print?
    1. class CAdd  
    2. {  
    3. public:  
    4.     CAdd():m_nSum(0){NULL;}  
    5.     int operator()(int i)  
    6.     {  
    7.         m_nSum += i;  
    8.         return m_nSum;  
    9.     }  
    10.       
    11.     int Sum() const  
    12.     {  
    13.         return m_nSum;  
    14.     }  
    15.       
    16. private:  
    17.     int m_nSum;  
    18. };  
    19. int main(int argc, const char * argv[])  
    20. {  
    21.     CAdd cAdd;  
    22.     function<int(int)> funcAdd1 = cAdd;  
    23.     function<int(int)> funcAdd2 = cAdd;  
    24.     cout<<funcAdd1(10)<<endl;  
    25.     cout<<funcAdd2(10)<<endl;  
    26.     cout<<cAdd.Sum()<<endl;  
    27.       
    28.      return 0;  
    29. }  

    上面的输出结果是 10 10 0。我们将同一个函数对象赋值给了两个function,然后分别调用这两个function,但函数中的成员变量的值没有保存,问题在哪里?因为function的缺省行为是拷贝一份传递给它的函数对象,于是f1,f2中保存的都是cAdd对象的拷贝。

    C++11提供了ref和cref函数来提供对象的引用和常引用的包装。要是function能够正确保存函数对象的状态,可以如下修改代码:

     

    [cpp] view plain copy
     
     print?
    1. function<int(int)> funcAdd3 = ref(cAdd);  
    2. function<int(int)> funcAdd4 = ref(cAdd);  
    3. cout<<funcAdd3(10)<<endl;  
    4. cout<<funcAdd4(10)<<endl;  
    5. cout<<cAdd.Sum()<<endl;  

     

            另外,两个function之间赋值时,如果源function保存的是函数对象的拷贝,则目标function保存的也是函数对象的拷贝。如果源function保存的是对函数对象的引用,则目标function保存的也是函数对象的引用。

  • 相关阅读:
    AtCoder Beginner Contest 070 (A B C D)
    sqlite数据库的两种增删改查、事物
    CloseableHttpClient设置超时
    mybatis注解大全
    log4j.properties通用配置
    log4j.xml常用配置
    redistempalate的超时设置的操作更新
    在maven项目中如何引入另外一个项目(转)
    eclipse找不到JadClipse问题
    JDK8的新特性——Lambda表达式
  • 原文地址:https://www.cnblogs.com/lidabo/p/7266885.html
Copyright © 2011-2022 走看看