【C++新特性】bind 函数和function 类模板

std::bind 函数

C++11 引入了新的标准库函数 bind,std::bind 函数定义在头文件 functional 中,是一个函数模板,它就像一个函数适配器,接受一个可调用对象(callable object),生成一个新的可调用对象来“适应”原对象的参数列表。

std::bind 将可调用对象与其参数一起进行绑定,绑定后的结果可以使用 std::function 保存。std::bind 主要有以下两个作用:

  • 将可调用对象和其参数绑定成一个防函数;
  • 只绑定部分参数,减少可调用对象传入的参数。

std::bind 函数有两种函数原型,定义如下:

template <class F, class... Args>
/* unspecified */ bind (Fn&& f, Args&&... args);

template <class Ret, class F, class... Args>
/* unspecified */ bind (Fn&& f, Args&&... args);

参数说明:

  • f:一个可调用对象(可以是函数对象、函数指针、函数引用、成员函数指针、数据成员指针),它的参数将被绑定到 args 上。
  • args:绑定参数列表,参数会被值或占位符(std::placeholders)替换,其长度必须与 f 接收的参数个数一致。

std::bind绑定普通函数

double my_divide (double x, double y) {return x/y;}
auto fn_half = std::bind (my_divide,_1,2);  
std::cout << fn_half(10) << '\n';                        // 5
  • bind 的第一个参数是函数名,普通函数做实参时,会隐式转换成函数指针。因此std::bind (my_divide,_1,2)等价于std::bind (&my_divide,_1,2);
  • _1表示占位符,位于 中:std::placeholders::_1;

std::bind绑定一个成员函数

struct Foo {
    void print_sum(int n1, int n2)
    {
        std::cout << n1+n2 << '\n';
    }
    int data = 10;
};

int main() 
{
    Foo foo;
    auto f = std::bind(&Foo::print_sum, &foo, 95, std::placeholders::_1);
    f(5); // 100
}
  • bind 绑定类成员函数时,第一个参数表示对象的成员函数的指针,第二个参数表示对象的地址。
  • 必须显示的指定 &Foo::print_sum,因为编译器不会将对象的成员函数隐式转换成函数指针,所以必须在 Foo::print_sum 前添加 &;
  • 使用对象成员函数的指针时,必须要知道该指针属于哪个对象,因此第二个参数为对象的地址 &foo;


std :: function 类模板

类模板 std :: function 是一个通用的多态函数包装器。 std :: function 的实例可以存储,复制和调用任何可调用的目标 :包括函数,lambda 表达式,绑定表达式或其他函数对象,以及指向成员函数和指向数据成员的指针。当 std::function 对象未包裹任何实际的可调用元素,调用该 std::function 对象将抛出 std::bad_function_call 异常。

原型如下:

template< class R, class... Args >
class function<R(Args...)>;

例如:std::function<int(int,int)> func;则 function 类的实例 func 可以指向返回值为 int 型,有两个形参都为 int 型的函数。

#include <functional>
#include <iostream>
int f(int a, int b)
{
  return a+b;
}
int main()
{
	std::function<int(int, int)>func = f;
	cout<<f(1, 2)<<endl; // 3
	system("pause");
	return 0;
}

我们再来先来看看以前 C 和 C++98 的用法:

#include<iostream>
using namespace std;

// c type global function
int c_func(int a, int b)
{
    return a + b;
}

// function object
struct functor
{
public:
    int operator() (int a, int b)
    {
        return a + b;
    }
};

int main()
{
   typedef int (*Func)(int ,int);
   Func func = c_func;
   cout<< func(1,2)<<endl; // 3
   
   functor ft;
   cout<<ft(1,2)<<endl; //3
   return 0;
}

从上面我们可以看出,使用 C++11 的 function 类调用函数方便多了。




参考链接:C++11 新特性总结

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值