c++中的std::bind与std::function

最近在看《深入应用c++11》的时候遇到了std::bind的一些新用法,之前没有遇到过,这里记录下。通常时候std::bind是与std::function一起结合使用的,std::bind是一个函数模板,而std::function是一个类模板,这个从其源码就可看出

  /**
   *  @brief Function template for std::bind.
   *  @ingroup binders
   */
  template<typename _Func, typename... _BoundArgs>
    inline typename
    _Bind_helper<__is_socketlike<_Func>::value, _Func, _BoundArgs...>::type
    bind(_Func&& __f, _BoundArgs&&... __args)
    {
      typedef _Bind_helper<false, _Func, _BoundArgs...> __helper_type;
      typedef typename __helper_type::__maybe_type __maybe_type;
      typedef typename __helper_type::type __result_type;
      return __result_type(__maybe_type::__do_wrap(std::forward<_Func>(__f)),
               std::forward<_BoundArgs>(__args)...);
    }
 template<typename _Signature>
    class function;

std::bind的常见用法
之前的理解仅仅是将bind当做绑定一个全局函数,现在又遇到了一些其他的用法,直接上代码吧

/*
 * main.cpp
 *
 *  Created on: 2017年12月3日
 *      Author: Administrator
 */
#include <iostream>
#include <functional>

void output(int x, int y)
{
    std::cout << x << " " << y << std::endl;
}
class A
{
public:
    int i_ = 0;

    void output(int x, int y)
    {
        std::cout << x << " " << y << std::endl;
    }

    void operator()() const //无参数 无返回值的仿函数
    {
        std::cout <<"仿函数"<< std::endl;
    }
};

int main(void)
{
    //1,绑定全局函数
    std::bind(output,1,2); //全局函数,仅仅是绑定,没有调用
    std::bind(output,1,2)();//绑定并调用全局函数

    //2,绑定成员函数
    A a;
    std::function<void(int, int)> fr =
        std::bind(&A::output, &a /*调用者*/, std::placeholders::_1, std::placeholders::_2);
    fr(1, 2);  //输出 1 2

    //3,绑定成员变量(包括静态的成员变量)
    std::function<int&(void)> fr_i = std::bind(&A::i_, &a/*调用者*/);  //vs13的bug,绑定成员变量要报错
    fr_i() = 123;

    std::cout << a.i_ << std::endl;  //输出 123
    std::cout << fr_i() << std::endl;  //输出 123

    A a1;
    std::function<int&(void)> fr_i_1 = std::bind(&A::i_, a1/*调用者*/); //调用者没有传指针
    fr_i_1() = 123;

    std::cout << a1.i_ << std::endl;  //输出 0
    std::cout << fr_i_1() << std::endl;  //输出 123

    //4,仿函数
    std::function<void(void)> op = std::bind(&A::operator(),a);
    op();

    return 0;
}

结果如下:

1 2
1 2
123
123
0
123
仿函数

另外,bind函数不能绑定重载函数,原因有待深究。
上面代码中,成员函数的入参是函数名,函数名是个指针,因此是取地址;而调用者的话没有要求,如果调用者是值拷贝,会发现实际的对象值还是未改变的,如上面结果中的0。

针对bind函数中的引用是右值引用,这里形参的话又涉及到引用折叠,后续继续研究

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值