C++ function、bind以及lamda表达式

http://blog.csdn.net/augusdi/article/details/11771699

首先说明一点,回调函数按我的理解就是函数名称(即函数的地址)作为函数参数在另一个函数中被使用。

function

 

    #include < functional>  
       
    std::function< size_t (const char*) > print_func;  
     //std::function< size_t (const char*) >是类型,print_func是变量  
    /// normal function -> std::function object  
    size_t CPrint(const char*) { ... }  
    print_func = CPrint;  
    print_func("hello world"):  
       
    /// functor -> std::function object  
    class CxxPrint  
    {  
    public:  
        size_t operator()(const char*) { ... }  
    };  
    CxxPrint p;  
    print_func = p;  
    print_func("hello world");  

 在上面的例子中,我们把一个普通的函数和一个functor()赋值给了一个std::function对象,然后我们通过该对象来调用。这样就很好解决了类型安全的问题(为什么这样,我还没理解)

所以说,std::function< size_t (const char*) > 可以看做是函数指针的类型,用来表示函数指针,可以叫做可调用实体。

std::function object最大的用处就是在实现函数回调,使用者需要注意,它不能被用来检查相等或者不相等

 

bind

bind是这样一种机制,它可以预先把指定可调用实体的某些参数绑定到已有的变量,产生一个新的可调用实体,即把函数名称、函数参数实现绑定好,留几个未绑定(等待使用者传入),得到一个新的可调用实体

 

    #include < functional>  
       
    int Func(int x, int y);  
    auto bf1 = std::bind(Func, 10, std::placeholders::_1);  
    bf1(20); ///< same as Func(10, 20)  
       
    class A  
    {  
    public:  
        int Func(int x, int y);  
    };  
       
    A a;  
    auto bf2 = std::bind(&A::Func, a, std::placeholders::_1, std::placeholders::_2);  
    bf2(10, 20); ///< same as a.Func(10, 20)  
       
    std::function< int(int)> bf3 = std::bind(&A::Func, a, std::placeholders::_1, 100);  
    bf3(10); ///< same as a.Func(10, 100)  

 bf2也可以不用auto直接用std::function<int(int ,int)>来声明

上面的例子中,bf1是把一个两个参数普通函数的第一个参数绑定为10,生成了一个新的一个参数的可调用实体体; bf2是把一个类成员函数绑定了类对象,生成了一个像普通函数一样的新的可调用实体; bf3是把类成员函数绑定了类对象和第二个参数,生成了一个新的std::function对象

 

  • (1)bind预先绑定的参数需要传具体的变量或值进去,对于预先绑定的参数,是pass-by-value的
  • (2)对于不事先绑定的参数,需要传std::placeholders进去,从_1开始,依次递增。placeholder是pass-by-reference的
  • (3)bind的返回值是可调用实体,可以直接赋给std::function对象
  • (4)对于绑定的指针、引用类型的参数,使用者需要保证在可调用实体调用之前,这些参数是可用的
  • (5)类的this可以通过对象或者指针来绑定

基本lambda表达式语法

 

    #include <iostream>  
    int main(int argc, char* argv[])  
    {  
        auto func = [] () { std::cout << "hello world"; };  
        func();  
        return 0;  
    }  

 好吧,你已经发现了lambda表达式,从[]开始,这个符号成为捕获规范它告诉我们正在创建一个lambda函数编译,你会发现每一个lamda表达式都有这样的开头表示(有些会稍有不同,后面会介绍到)。

接下来,像其他任何函数一样,需要一个参数列表,哪里是返回值的描述呢?事实证明我们不需要,因为在C++11标准中,编译器可以推断lambda函数的返回值,它会做而不是强迫你加上它

下一行func()中,我们称之为lambda函数,它看起来就像调用其他任何函数一样,顺便说一下,这样来,你就不需要定义一个函数,然后用一个函数指针指向它。

 

 默认情况下,lambda表达式不写返回语句,它缺省值为空,如果你有一个简单的返回表达式,编译器也会推断返回值的类型。

[] () { return 1; } // compiler knows this returns an integer 

如果你写一个更复杂的lambda函数,与一个以上的返回值,你必须指定返回类型

[] () -> int { return 1; } // now we‘re telling the compiler what we want 

 

 

    typedef int (*func)();  
    func f = [] () -> int { return 2; };  
    f();  

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。