std::bind 是一个C++函数模板,简单说它就像一个函数适配器,用来接受一个可调用对象(callable object),生成一个新的可调用对象来“适应”原对象的参数列表。 该函数模板定义在头文件 #include
C++中的可调用对象:函数、函数指针、lambda表达式、bind对象、函数对象。lambda表达式和bind对象是C++新标准中提出的,其他可调用对象在旧标准中就已存在。
bind 可以把一个原本接收 N 个参数的函数 origFunc(...),通过绑定(个人觉得此处的绑定让人难以理解 bind 的作用,感觉用固定或者给定更好理解)一些参数,返回一个接收 M 个(一般情况M小于N,当大于等于N时似乎多的参数没有实际意义)参数的新函数 newFunc(...)。同时,使用 std::bind 还可以实现参数顺序的调整等操作。
- // FUNCTION TEMPLATE bind (implicit return type)
- template <class _Fx, class... _Types>
- _NODISCARD _CONSTEXPR20 _Binder<_Unforced, _Fx, _Types...> bind(_Fx&& _Func, _Types&&... _Args) {
- return _Binder<_Unforced, _Fx, _Types...>(_STD forward<_Fx>(_Func), _STD forward<_Types>(_Args)...);
- }
-
- // FUNCTION TEMPLATE bind (explicit return type)
- template <class _Ret, class _Fx, class... _Types>
- _NODISCARD _CONSTEXPR20 _Binder<_Ret, _Fx, _Types...> bind(_Fx&& _Func, _Types&&... _Args) {
- return _Binder<_Ret, _Fx, _Types...>(_STD forward<_Fx>(_Func), _STD forward<_Types>(_Args)...);
- }
上述函数原型为 VS2019 中的具体模板,可以看到 std::bind 有两种函数原型。
作用:用来返回基于 _Fx 的函数对象,参数被绑定到可变参数 _Args 中。每个参数都可以绑定到一个值或者一个占位符(bind 返回的 newFunc(..,) 的参数)。
- #include
- void addTwoNum(int a, int b) {
- cout << "a+b= " << a + b << endl;
- }
- struct INFOS {
- int year;
- int month;
- int day;
- void mergeDay() {
- string ret_str;
- ret_str = to_string(year) + "-" + to_string(month) + "-" + to_string(day);
- cout << "merged date info: " << ret_str << endl;
- }
- };
- int main() {
- // bind 绑定函数
- auto calSum = bind(addTwoNum, 1, std::placeholders::_1);
- calSum(10);
- auto calSum1 = bind(addTwoNum, 2, 3);
- calSum1();
- // bind 绑定函数成员对象
- INFOS information = {2022, 2, 23};
- auto dayInfos = bind(&INFOS::day, &information);
- cout << "day infos: " << dayInfos() << endl;
- auto mergeDate = bind(&INFOS::mergeDay, &information);
- mergeDate();
-
- INFOS infos = {2018, 8, 7};
- auto mergeDateUsNewParms = bind(&INFOS::mergeDay, std::placeholders::_1);
- mergeDateUsNewParms(infos);
-
- return 0;
- }
- /// Terminal output results:
- a+b= 11
- a+b= 5
- day infos: 23
- merged date info: 2022-2-23
- merged date info: 2018-8-7
由于可调用对象的定义方式较多,但是函数的调用方式较为类似,因此需要使用一个统一的方式保存可调用对象或者传递可调用对象。std::function 就可以实现该需求。
std::function 是一个通用的、多态的可调用对象包装器,是一个类模板,可以容纳除了类成员函数指针之外的所有可调用对象(普通函数、Lambda表达式、函数指针、以及其它函数对象等),它可以用统一的方式处理函数、函数对象、函数指针,并允许保存和延迟它们的执行。可以对可以调用的目标实体进行存储、复制、和调用操作。
通过 std::function 可以形成一个新的可调用的std::function对象;让我们不再纠结那么多的可调用实体。
std::function 对象是对C++中现有的可调用实体的一种类型安全的包装(因为函数指针这类可调用实体,是类型不安全的)。
- int add(int a, int b) {
- return a + b;
- }
- auto multiply = [](int a, int b) {
- return a * b;
- };
- struct divs {
- int operator() (int a, int b) {
- return a / b;
- }
- };
-
- int main() {
- function<int(int, int)> addTwoNum = add;
- function<int(int, int)> multiTwoNum = multiply;
- function<int(int, int)> divTwoNum = divs();
-
- cout << addTwoNum(12, 23) << endl;
- cout << multiTwoNum(2, 4) << endl;
- cout << divTwoNum(12, 4) << endl;
- return 0;
- }
- /// Terminal output results:
- 35
- 8
- 3