C++ 中std::function 、std::bind的使用和lambda的使用

  1. std::function是可调用对象的包装器;std::bind是将可点用对象和其参数一起进行绑定,且绑定后的结果可以使用std::function对象进行保存,并延迟调用到需要调用的时候;
  2. 在C++中,可调用实体主要包括函数,函数指针,函数引用,可以隐式转换为函数指定的对象,或者实现了opetator()的对象(即C++98中的functor)。C++0x中,新增加了一个std::function对象,std::function对象是对C++中现有的可调用实体的一种类型安全的包裹(我们知道像函数指针这类可调用实体,是类型不安全的)。
  3. bind是这样一种机制,它可以预先把指定可调用实体的某些参数绑定到已有的变量,产生一个新的可调用实体,这种机制在回调函数的使用过程中也颇为有用。C++98中,有两个函数bind1st和bind2nd,它们分别可以用来绑定functor的第一个和第二个参数,它们都是只可以绑定一个参数。各种限制,使得bind1st和bind2nd的可用性大大降低。C++0x中,提供了std::bind,它绑定的参数的个数不受限制,绑定的具体哪些参数也不受限制,由用户指定,这个bind才是真正意义上的绑定,有了它,bind1st和bind2nd就没啥用武之地了,因此C++0x中不推荐使用bind1st和bind2nd了,都是deprecated了。
  4. C++11 的 lambda 表达式规范如下:

    [ capture ] ( params ) mutable exception attribute -> ret { body }(1) 
    [ capture ] ( params ) -> ret { body }(2) 
    [ capture ] ( params ) { body }(3) 
    [ capture ] { body }(4) 

    其中

    • (1) 是完整的 lambda 表达式形式,
    • (2) const 类型的 lambda 表达式,该类型的表达式不能改捕获("capture")列表中的值。
    • (3)省略了返回值类型的 lambda 表达式,但是该 lambda 表达式的返回类型可以按照下列规则推演出来:
      • 如果 lambda 代码块中包含了 return 语句,则该 lambda 表达式的返回类型由 return 语句的返回类型确定。
      • 如果没有 return 语句,则类似 void f(...) 函数。
    • 省略了参数列表,类似于无参函数 f()。

    mutable 修饰符说明 lambda 表达式体内的代码可以修改被捕获的变量,并且可以访问被捕获对象的 non-const 方法。

    exception 说明 lambda 表达式是否抛出异常(noexcept),以及抛出何种异常,类似于void f(throw(X, Y)。

    attribute 用来声明属性。

    另外,capture 指定了在可见域范围内 lambda 表达式的代码内可见得外部变量的列表,具体解释如下:

    • [a,&b] a变量以值的方式呗捕获,b以引用的方式被捕获。
    • [this] 以值的方式捕获 this 指针。
    • [&] 以引用的方式捕获所有的外部自动变量。
    • [=] 以值的方式捕获所有的外部自动变量。
    • [] 不捕获外部的任何变量。

    此外,params 指定 lambda 表达式的参数。

  5. 测试用例:

    1、std::function作为回调函数使用示例

    

class A
{
std::function<void()> callback_;
public:
A(const std::function<void()>& f) :callback_(f){}
void Notify()
{
callback_();
}
};
class Foo
{
public:
void operator()(void)
{
std::cout << __FUNCTION__ << std::endl;//get the func name

}
};
void Test8()
{
Foo foo;
A a(foo);
a.Notify();
}

  2、std::function 和std::bind 结合使用:

void call_when_event(int x, const std::function<void(int)>& func)
{
    if (!(x & 1))
    {
        //cout << x << endl;
        func(x);
    }
}

void call_when_event1(int x,int y, const std::function<void(int,int)>& func)
{
    if (!(x & 1))
    {
        //cout << x << endl;
        func(x,y);
    }
}
void output(int x)
{
    cout << x << endl;
}
void output_add_2(int x,int y)
{
    cout << x + y << endl;
}
void Test7()
{
    auto fr = std::bind(output, std::placeholders::_1);
    for (int i = 0; i < 10; i++)
    {
        call_when_event(i, fr);
    }
    std::cout << std::endl;

    auto fr1 = std::bind(output_add_2, std::placeholders::_1,std::placeholders::_2);
    for (int i = 0; i < 10; i++)
    {
        call_when_event1(i, i,fr1);
    }
}
3、lambda 测试用例:
返回vector中大于5小于10的元素的个数:
void Test5()
{
    std::vector<int> coll;
    for (int i = 0; i <= 10; i++)
    {
        coll.push_back(i);
    }
    int count = std::count_if(coll.begin(), coll.end(), [](int x){return x > 5 && x < 10; });
    std::cout << count << std::endl;

}
 
  

 

 

 

转载于:https://www.cnblogs.com/KunLunSu/p/7967428.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值