C++ std::funtion 可调用函数 std::bind

本文深入探讨了C++中std::function和std::bind的使用,解释了可调用对象的概念,并展示了如何利用std::bind绑定函数、成员函数及成员变量,实现灵活的函数调用。

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

一、std::funtion

template.h

#pragma once
#include <iostream>
#include <map>
#include <functional>

class RC
{
public:
	void operator()(int tv)
	{
		std::cout << "RC operator:" << tv << std::endl;
	}
};

void myrcFun(int tv)
{
	std::cout << "myrcFun:" << tv << std::endl;
}

class RC2
{
public:
	using tfpoint = void(*)(int);
	static void myfunc(int tv)
	{
		std::cout << "RC2 static myfunc:" << tv << std::endl;
	}
	operator tfpoint() { return myfunc; }
};

main.cpp

#include <iostream>
#include "template.h"
using namespace std;
int main()
{
	std::function<void(int)> f1 = myrcFun;
	f1(100);

	std::function<void(int)> f2 = RC2::myfunc;
	f2(200);

	RC rc;
	std::function<void(int)> f3 = rc;//可调用对象,调用了operator()
	f3(300);

	RC2 rc2;
	std::function<void(int)> f4 = rc2;//可调用对象,类型转换运算符,operator tfpoint() { return myfunc; }转为为指针
	f4(300);
}

为什么叫可调用对象呢?

RC rc;
rc(4);

实际上是调用RC类的operator(),但看上去像用对象直接调用了函数,所以叫做可调用对象。

二、std::bind

template.h

#pragma once
#include <iostream>
#include <map>
#include <functional>

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

void myfun2(int &x, int& y)
{
	x++;
	y++;
}

class QT
{
public:
	void myfunc(int x, int y)
	{
		std::cout << "x:" << x << ",y:" << y << std::endl;
		m_a = x;
	}

	int m_a = 0;
};

class RC
{
public:
	void operator()(int tv)
	{
		std::cout << "RC operator:" << tv << std::endl;
	}
};

main.cpp

#include <iostream>
#include "template.h"
using namespace std;
int main()
{
    //绑定函数
    auto bf2 = std::bind(myfun1, placeholders::_1, placeholders::_2, 100);
    bf2(3, 4);

    int test1 = 2;
    int test2 = 3;
    auto bf4 = std::bind(myfun2, test1, placeholders::_1);
    bf4(test2);
    cout << "test1:" << test1 << "test2:" << test2 << endl;//输出为2和4,因为提前绑定了test1,所以是值传递

    //绑定成员函数
    QT qt;
    auto qtfunction = std::bind(&QT::myfunc, &qt, placeholders::_1, placeholders::_2);//注意这里已经要传递引用,不然会调用拷贝构造函数,生成新qt对象。myfunc修改的成员变量不是针对原qt对象,而是新qt对象。原qt对象的成员变量不会被改变
    qtfunction(10, 20);

    //绑定成员变量
    std::function<void(int, int)> qtfunc1 = std::bind(&QT::myfunc, &qt, placeholders::_1, placeholders::_2);
    std::function<int &(void)> qtVar = std::bind(&QT::m_a, &qt);
    qtVar() = 40;

    //绑定可调用对象
    auto rcfun1 = std::bind(RC(), 2);
    rcfun1();
}

std::bind除了类似std::funtion可以绑定函数外,还可以指定参数。

输出:

x:3,y:4,z:100
test1:2,test2:4
x:10,y:20
RC operator:2

### 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、付费专栏及课程。

余额充值