C++11中提供了std::bind
。bind()函数的意义就像它的函数名一样,是用来绑定函数调用的某些参数的。
bind的思想实际上是一种延迟计算的思想,将可调用对象保存起来,然后在需要的时候再调用。而且这种绑定是非常灵活的,不论是普通函数、函数对象、还是成员函数都可以绑定,而且其参数可以支持占位符,比如你可以这样绑定一个二元函数:
auto f = bind(&func, std::placeholders::_1, std::placeholders::_2);
调用的时候通过f(1,2)实现调用。所以,我们可简单的认为std::bind
就是std::bind1st
和std::bind2nd
的加强版。
std::bind函数有两种函数原型,定义如下:
template< class F, class... Args >
/*unspecified*/ bind( F&& f, Args&&... args );
template< class R, class F, class... Args >
/*unspecified*/ bind( F&& f, Args&&... args );
Parameters
f | - | Callable object (function object, pointer to function, reference to function, pointer to member function, or pointer to data member) that will be bound to some arguments |
args | - | list of arguments to bind, with the unbound arguments replaced by the placeholders _1, _2, _3... of namespace std::placeholders |
这里要先学习仿函数。请参考仿函数的使用
实例1
#include <iostream>
#include <functional>
using namespace std;
int TestFunc(int a, char c, float f)
{
cout << a << endl;
cout << c << endl;
cout << f << endl;
return a;
}
int main()
{
auto bindFunc1 = bind(TestFunc, std::placeholders::_1, 'A', 100.1);
bindFunc1(10); //等于TestFunc(10,'A', 100.1)
cout << "=================================\n";
auto bindFunc2 = bind(TestFunc, std::placeholders::_2, std::placeholders::_1, 100.1);
bindFunc2('B', 10); //等于TestFunc(10,'B', 100.1)
cout << "=================================\n";
auto bindFunc3 = bind(TestFunc, std::placeholders::_2, std::placeholders::_3, std::placeholders::_1);
bindFunc3(100.1, 30, 'C'); //等于TestFunc(30,'C', 100.1)
return 0;
}
上面这段代码主要说的是bind中std::placeholders的使用。 std::placeholders是一个占位符。当使用bind生成一个新的可调用对象时,std::placeholders表示新的可调用对象的第 几个参数和原函数的第几个参数进行匹配。
auto bindFunc3 = bind(TestFunc, std::placeholders::_2, std::placeholders::_3, std::placeholders::_1);
bindFunc3(100.1, 30, 'C');
可以看到,在bind的时候,第一个位置是TestFunc,除了这个,参数的第一个位置为占位符std::placeholders::_2,这就表示,调用bindFunc3的时候,它的第二个参数——即30,和TestFunc的第一个参数匹配,所以std::placeholders::_2为30,以此类推,最后,实际执行的是TestFunc(30,'C', 100.1)。
实例2
#include <random>
#include <iostream>
#include <memory>
#include <functional>
void f(int n1, int n2, int n3, const int& n4, int n5)
{
std::cout << n1 << ' ' << n2 << ' ' << n3 << ' ' << n4 << ' ' << n5 << '\n';
}
int g(int n1)
{
return n1;
}
struct Foo {
void print_sum(int n1, int n2)
{
std::cout << n1 + n2 << '\n';
}
int data = 10;
};
int main()
{
using namespace std::placeholders; // for _1, _2, _3...
// demonstrates argument reordering and pass-by-reference
int n = 7;
// (_1 and _2 are from std::placeholders, and represent future
// arguments that will be passed to f1)
auto f1 = std::bind(f, _2, 42, _1, std::cref(n), n);
n = 10;
f1(1, 2, 1001); // 1 is bound by _1, 2 is bound by _2, 1001 is unused
// makes a call to f(2, 42, 1, n, 7)
// nested bind subexpressions share the placeholders
auto f2 = std::bind(f, _3, std::bind(g, _3), _3, 4, 5);
f2(10, 11, 12); // makes a call to f(12, g(12), 12, 4, 5);
// bind to a pointer to member function
Foo foo;
auto f3 = std::bind(&Foo::print_sum, &foo, 95, _1);
f3(5);
// bind to a pointer to data member
auto f4 = std::bind(&Foo::data, _1);
std::cout << f4(foo) << '\n';
std::cout << f4(std::make_shared<Foo>(foo)) << '\n'
<< f4(std::make_unique<Foo>(foo)) << '\n';
return 0;
}
参考:
https://en.cppreference.com/w/cpp/utility/functional/bind
https://blog.csdn.net/qq_37653144/article/details/79285221
https://blog.csdn.net/u013654125/article/details/100140328#commentBox
到此这篇关于C++ std::bind用法详解的文章就介绍到这了,更多相关C++ std::bind用法内容请搜索html5模板网以前的文章希望大家以后多多支持html5模板网!