C++入门学习:std::function,std::bind,std::placeholders

一.std::function

std::function 是一个模板类

作用是对C++中的可调用对象进行包装,包括普通函数、成员函数、模板函数、静态函数、lambda表达式等。

它的最基本的作用是,简化调用的复杂程度,统一调用的方式。

声明方式:

std::function< 返回值类型 ( 参数类型1, 参数类型2, ...) >

二.std::bind
std::bind是一个函数模板,就像是一个函数适配器,接受一个可调用对象,而生成一个新的可调用对象来适配原来的参数列表,该模板返回的是一个std::function对象。用该函数我们也能实现参数顺序的调整和给将指定参数设置成固定值。

function 与 bind 结合后,便成为了 C++ 中类成员函数作为回调函数的一种规范的实现方式。

三.std::placeholders
占位符,c++11中有29个占位符,分别是_1~_29,一般情况下是std::placeholders::_1这样的。占位符的作用就是用来代表参数的,std::placeholders::_1表示的是std::bind得到的std::function对象被调用时,传入的第一个参数,而std::placeholders::_2则是第二个参数。

我们调整std::placeholders::_x在std::bind时的顺序,就可以起到调整参数顺序的作用了。此外,我们也可以在std::bind的时候不用std::placeholders::_x,而直接写成固定的值,这样子调用std::function存储的对象时,对应位置的参数将是固定值。

四.例子
 1.普通函数:

 头文件

#include <functional>
#include <iostream>
using namespace std;
int Subtract_(int a, int b)
{
    std::cout << "Subtract_: " << a << " " << b<< endl;
    return a-b;
}
 
int main()
{
    std::function<int(int, int)> func1 = Subtract_;
    int ret = func1(1, 2);
    cout << ret << endl;
    auto f1 = std::bind(Subtract_, std::placeholders::_1, std::placeholders::_2);
    auto f2 = std::bind(Subtract_, std::placeholders::_2, std::placeholders::_1);
    auto f3 = std::bind(Subtract_, std::placeholders::_1, 100);
    cout << f1(30, 66) << endl;
    cout << f2(30, 66) << endl;
    cout << f3(30, 66) << endl;
 
    return 0;
}

结果

Subtract_: 1 2
-1
Subtract_: 30 66
-36
Subtract_: 66 30
36
Subtract_: 30 100
-70

2.模板函数

template <class T>
T MouldSubtract(T a, T b)
{
    return a - b;
}
 
int main()
{
    std::function<double(double, double)> func2 = MouldSubtract<double>;
    cout << func2(50, 6.6) << endl;
    auto f4 = std::bind(MouldSubtract<double>, std::placeholders::_1, std::placeholders::_2);
    auto f5 = std::bind(MouldSubtract<double>, std::placeholders::_2, std::placeholders::_1);
    auto f6 = std::bind(MouldSubtract<double>, std::placeholders::_1, 100);
    cout << f4(50, 6.6) << endl;
    cout << f5(50, 6.6) << endl;
    cout << f6(50, 6.6) << endl;
 
    return 0;
}

结果

43.4

3.类普通成员函数

class TestClass
{
public:
    int Subtract_(int a, int b)
    {
        std::cout << "Subtract_: " << a << " " << b << endl;
        return a - b;
    }
};
 
int main()
{
    TestClass test;
    std::function<int(int, int)> func3  = std::bind(&TestClass::Subtract_,&test, std::placeholders::_1, std::placeholders::_2);
    cout << func3(30, 66) << endl;
 
    return 0;
}

结果

Subtract_: 30 66
-36

4.类静态成员函数

class TestClass
{
public:
    int Subtract_(int a, int b)
    {
        std::cout << "Subtract_: " << a << " " << b << endl;
        return a - b;
    }
    static int StaticFunc(int a) { return a+100; }
};
 
int main()
{
    std::function<int(int)> func4 = &TestClass::StaticFunc;
    cout << func4(36)<< endl;
 
    return 0;
}

结果

136

5.lambda表达式

int main()
{
    std::function<int(int,int)>  func5 = [](int a, int b) -> int
    {
        return a - b;
    };
    cout << func5(36, 100) << endl;
 
    return 0;
}

 6.综合使用

#include <functional>
#include <iostream>
using namespace std;
 
class BindTest
{
public:
    BindTest();
    void connect(std::function<int(int, int)> func)
    {
        m_func = func;
    }
    int addSlot(int a, int b) { return a + b; }
    std::function<int(int, int)> m_func;
 
    int signal(int a, int b)
    {
        int result = m_func(a, b);
        //cout <<"signal:"<< result << endl;
        return result;
    }
};
 
BindTest::BindTest()
{
    // 1. 成员函数作为回调函数,类内调用时,第一个参数需要填this指针。
    // connect(std::bind(&BindTest::addSlot, this, placeholders::_1, placeholders::_2));
 
    //3
    connect([this](int a,int b)->int{
        int result = addSlot(a,b);
       cout<<"lambda:"<<result<<endl;
       return result;
    });
}
 
int main(int argc, char **argv)
{
    BindTest test;
    // 2. 外部调用时,将类实例本身的地址作为this指针传入
    // test.connect(bind(&BindTest::addSlot, &test, placeholders::_1, placeholders::_2));
 
    //1,2,3
    cout << "   "<<test.signal(55, 2)<<endl;
 
    // 4
    function<int(int,int)> call = bind(&BindTest::addSlot, &test, placeholders::_1, placeholders::_2);
    cout<<"fun4:"<<call(55,2)<<endl;
 
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值