std::function 和 std::bind

可调用对象

  1. 是一个函数指针
  2. 是一个具有operator()成员函数的类对象(仿函数)
  3. 是一个可被装换为函数指针的类对象
  4. 是一个类的成员(函数)指针
void func()
{

}

struct Foo
{
    void operator()(void)
    {
        
    }
};

struct Bar
{
    using fr_t = void(*)(void);
    static void func(void)
    {
    }
    
    operator fr_t(void)
    {
        return func;
    }
};

struct A
{
    int a_;
    void mem_func(void)
    {
    }
};

int main()
{
    void(*func_ptr)(void) = &func;            //函数指针
    func_ptr();

    Foo foo;                                                        //仿函数
    foo();    
    
    Bar bar;
    bar();                                                             //可被转换为函数指针的类的对象

    void(A::*mem_func_ptr)(void) = &A::mem_func;        //类成员函数指针
    int A::*mem_obj_ptr = &A::a_;                                            //类成员指针

    A aa;
    (aa.*mem_func_ptr)();
    aa.*mem_obj_ptr = 123;

    return 0;
}

std::function

  std::function是可调用对象的包装器,可以容纳除了类成员(函数)指针之外的所有可调用对象。通过指定它的模板参数,它可以用统一的方式处理函数、函数对象、函数指针,并允许保存和延迟执行它们。

#include <iostream>
#include <functional>

using namespace std;

void func(void)
{
    std::cout << __FUNCTION__ << std::endl;
}

class Foo
{
public:
    static int foo_func(int a)
    {
        std::cout << __FUNCTION__ << std::endl;
        return a;
    }
};

class Bar
{
public:
    void operator()(void)
    {
        std::cout << __FUNCTION__ << std::endl;
    }
};

class A
{
    std::function<void()> callback_;
public:
    A(const std::function<void()>& f):callback_(f)
    {
        
    }

    void notify(void)
    {
        callback_();
    }
};

void call_when_even(int x, const std::function<void(int)>& f)
{
    if(!(x & 1))
    {
        f(x);
    }
}

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

int main()
{
    std::function<void(void)> fr1 = func;           //普通函数
    fr1();

    std::function<int(int)> fr2 = Foo::foo_func;    //类的静态成员函数
    std::cout << fr2(123) << std::endl;

    Bar bar;                                        //仿函数
    fr1 = bar;
    fr1();

    A aa(bar);
    aa.notify();

    for (size_t i = 0; i < 10; i++)
    {
        call_when_even(i, output);
    }
    std::cout << std::endl;
    
    return 0;
}

std::bind

  std::bind用来将可调用对象与其参数一起进行绑定。绑定后的结果可以使用std::function进行保存,并延迟调用到任何我们需要的时候

  1. 将可调用对象与其参数一起绑定成一个仿函数
  2. 将多元(参数个数为n,n>1)可调用对象转成一元或者(n-1)元可调用对象,即只绑定部分参数
class B
{
public:
    std::string name_;
    void output(int x, int y)
    {
        std::cout << x << " " << y << std::endl;
    }
};

int main()
{
    B b;
    std::function<void(int,int)> fr = std::bind(&B::output, &b, std::placeholders::_1, std::placeholders::_2);
    fr(1,2);

    std::function<std::string&(void)> fr_s = std::bind(&B::name_, &b);
    fr_s() = "hello";

    std::cout << b.name_ << std::endl;
    
    return 0;
}

内容来源于:深入应用C++11 代码优化与工程级应用

猜你喜欢

转载自www.cnblogs.com/s3320/p/12120489.html