介绍c++
C++ 这门编程语言的历史可以追溯至 1979 年,当时的 Bjarne Stroustrup(C++ 之父,后续简称 Stroustrup)还在使用 Simula 语言进行开发工作。
1998年,C++ 标准委员会发布了第一版 C++ 标准,并将其命名为 C++98 标准。据不知名人士透露,《带注释的C++参考手册》这本书对 C++98 标准的制定产生了很大的影响。
2011年,新的 C++11 标准诞生,用于取代 C++98 标准。
2014年,C++14 标准发布,该标准库对 C++11 标准库做了更优的修改和更新;
2017年底,C++17 标准正式颁布;
std::bind原型
查看bind函数,发现它实际为两个模板函数。
1 2 3 4 5 6 7 8 9 10 11
| 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)...); }
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)...); }
|
它实际上是使用一个可调用对象,通过绑定一些参数生成一个新的可调用对象。这里注意一下细节,说的是可调用对象而不是可调用接口函数。
std::bind绑定的可调用对象有:
- 普通函数,静态函数,模板函数;
- 类成员函数,类成员静态函数,类成员模板函数,类成员变量,类内部绑定;
- 仿函数,Lambda表达式。
std::bind使用
绑定1
绑定普通函数,静态函数,模板函数。举例说明:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| void fun1(int i, int j) { cout << (i > j ? i : j) << endl; }
static void fun2(int i, int j) { cout << (i > j ? i : j) << endl; }
template <typename T1 = int, typename T2 = int> void fun3(T1 i, T2 j) { cout << (i > j ? i : j) << endl; }
int main() { auto fun1Test = bind(fun1, 1, 2); auto fun2Test = bind(fun2, 1, 2); auto fun3Test = bind(fun3<>, 1, 2);
fun1Test(); fun2Test(); fun3Test();
return 0; }
|
结果都为2。
绑定2
类成员函数、类成员静态函数、类成员模板函数、类成员变量、类内部绑定。
这部分比较重要的就是要明白普通函数和类成员函数有什么区别,我们都知道的是在函数指针上面,类成员函数指针不仅要指定目标函数的形参列表和返回类型,还必须指出成员函数所属的类。
当然类的静态成员不属于任何对象,因此无须特殊的指向静态成员的指针,指向静态成员的指针与普通指针没有什么区别。
所以我们在bind类成员函数时,需要显示的传入类对象、或者类对象的引用、或者类对象的指针
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| class Test { public: void fun1(int i, int j) { cout << (i > j ? i : j) << endl; }
static void fun2(int i, int j) { cout << (i > j ? i : j) << endl; }
template <typename T1 = int, typename T2 = int> void fun3(T1 i, T2 j) { cout << (i > j ? i : j) << endl; }
void fun4() { auto fun1Test = bind(&Test::fun1, this, 1, 2); fun1Test(); };
public: int m_X = 10; };
int main() { Test test; Test* pTest = &test; auto fun1Test = bind(&Test::fun1, test, 1, 2); auto fun2Test = bind(Test::fun2, 1, 2); auto fun3Test = bind(&Test::fun3<>, &test, 1, 2); auto memberVar = std::bind(&Test::m_X, pTest);
fun1Test(); fun2Test(); fun3Test(); test.fun4(); cout << memberVar() << endl;
return 0; }
|
绑定3
绑定仿函数、Lambda表达式。
1 2 3 4 5 6 7 8 9 10 11 12 13
| class Compare { public: void operator()(int i, int j) { cout << (i > j ? i : j) << endl; } };
int main() { auto fun1 = bind(Compare(), 1, 2); auto fun2 = bind([](int i, int j) {cout << (i > j ? i : j) << endl; }, 1, 2); fun1(); fun2(); return 0; }
|
占位符
占位符是用于表明要绑定的参数在生成新的可执行对象的位置。有的时候我们不需要立马进行绑定,或者不需要全部进行绑定,甚至是需要改变参数传入的顺序时候使用。
1 2 3 4 5 6 7 8 9 10 11 12
| void fun(int i, int j = 2) { cout << (i > j ? i : j) << endl; }
int main() { auto fun1 = bind(fun, 1, std::placeholders::_1); auto fun2 = bind(fun, std::placeholders::_1, 2); auto fun3 = bind(fun, std::placeholders::_2, std::placeholders::_1); fun1(2); fun2(1); fun3(1, 2); return 0; }
|
转自:https://blog.csdn.net/qq_42956179/article/details/115518826