std::function和bind绑定器

本文详细介绍了C++中的可调用对象概念及其多种定义方式,包括函数指针、仿函数、可转换为函数指针的类对象及类成员函数指针。此外,还深入探讨了C++11引入的std::function和std::bind如何统一处理各种可调用对象,简化了编程流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

可调用对象(callable objects)有如下几种定义

  • 是一个函数指针
  • 是一个具有operator()成员函数的类对象(仿函数)
  • 是一个可被转换为函数指针的类对象
  • 是一个类成员(函数)指针
void func(void)
{
    //.....
}
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_obj_ptr;//类成员函数指针
    int A::*mem_obj_ptr = &A::a_;//类成员指针
    A aa;
    (aa.*mem_func_ptr)();
    aa.*mem_obj_ptr = 123;

C++11通过提供std::function和std::bind统一了可调用对象的各种操作


std::function     -----------可调用对象包装器

std::function是一个类模板,可以容纳除了类成员(函数)指针之外的所有可调用对象。通过指定它的模板参数,它可以用统一的方法处理函数、函数对象、函数指针,并允许保存和延迟释放它们。std::function对象是对C++中现有的可调用实体的一种类型安全的包裹(我们知道像函数指针这类可调用实体,是类型不安全的)。通常std::function是一个函数对象类,它包装其它任意的函数对象,被包装的函数对象具有类型为T1, …,TN的N个参数,并且返回一个可转换到R类型的值。std::function使用 模板转换构造函数接收被包装的函数对象;特别是,闭包类型可以隐式地转换为std::function。

最简单的可以理解为:

通过std::function对C++中各种可调用实体(普通函数、Lambda表达式、函数指针、以及其它函数对象等)的封装,形成一个新的可调用的std::function对象;让我们不再纠结那么多的可调用实体。

std::function可以取代函数指针的作用。因为它可以保存函数延迟执行,所以比较适合做回调函数。代码如下:

/********回调函数的实现***************************/
class A
{
	std::function<void()> callback_;//返回void不接受任何参数
public:
	A(const std::function<void()>& f)
	:callback_(f){}
	void notify(void)
	{
		callback_();
	}
};
class Foo
{
public:
	void operator()(void)
	{
		cout<<__FUNCTION__<<endl;
	}
};
int main()
{
        Foo foo;
	A aa(foo);
	aa.notify();
	return 0;
}

作为参数传递的应用:

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

}

 

### C++ 中 `std::function` `std::bind` 的用法及区别 #### 定义与基本概念 `std::function` 是一种通用多态函数封装器,可以存储任何可调用对象(如普通函数、lambda 表达式、绑定表达式或其他函数对象)。其灵活性使得它能够作为回调机制的一部分,在事件驱动编程其他场景下非常有用。 ```cpp #include <functional> #include <iostream> void simpleFunction(int a) { std::cout << "Value is: " << a << '\n'; } int main() { // 创建一个 std::function 对象并赋值给简单函数 std::function<void(int)> f = simpleFunction; f(42); } ``` 另一方面,`std::bind` 提供了一种方式来创建新的可调用对象,这些新对象可以通过固定某些参数或将多个可调用实体组合在一起的方式简化现有可调用目标的接口。通过 bind 可以提前设置部分参数,从而减少后续调用时传递相同参数的需求[^1]。 ```cpp #include <functional> #include <iostream> class MyClass { public: void memberFunc(int i, double d) const { std::cout << "Integer value: " << i << ", Double Value:" << d << "\n"; } }; int main(){ using namespace std::placeholders; MyClass obj; // 绑定成员函数到特定实例,并预先设定第一个参数 auto boundMember = std::bind(&MyClass::memberFunc, &obj, _1, 3.14); // 调用已绑定的对象只需要提供剩余未固定的参数即可 boundMember(7); } ``` #### 主要差异点 - **目的不同**: `std::function` 更侧重于作为一个容器去保存各种类型的可调用对象;而 `std::bind` 则专注于调整已有可调用对象的行为模式,比如预设一些输入参数。 - **使用场合的区别**: 当需要定义一个能接受多种不同类型但签名兼容的函数指针的地方时,应该优先考虑使用 `std::function`; 如果想要改变某个具体函数或方法的工作方式,则可以选择 `std::bind`. - **性能考量**: 在大多数情况下,直接使用 lambda 表达式可能比使用 `std::bind` 效率更高,因为后者可能会引入额外的小型分配开销以及间接层。然而对于复杂情况下的参数绑定操作来说,`std::bind` 还是有它的优势所在[^2].
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值