声明
截至目前,它的声明如下
需要包含头文件
#include <functional>
std::bind是一个标准函数对象,作为一个函数对象适配器(function adaptor),可接受一个函数作为输入,并可绑定一个或多个被引用函数中的形参(同时允许将他们重新排列),最终返回一个新的函数对象作为输出。
通俗一点,也就是可以将设计好的函数和它所需要用到的形参(传入的形参位置可以调控)绑定起来作为一个单独对象(这种处理方法多用在多线程上)
例子
假设我们设计好了一个打印函数
void PrintNum(int first, int second)
{
std::cout<<first<<" "<<second;
}
std::bind可对这个加法函数进行取址后作为它的一个参数,并允许将该函数所需要用到的形参引入到它后面的参数列表中。
auto print_func = std::bind(&PrintNum, std::placeholders::_1, std::placeholders::_2);
*其中std::placeholders::_1代表占位符,用来告诉编译器这个是待填值
当我们要调用时,可以使用
print_func(1,2);
编译器会在看到这条指令后去调用PrintNum()函数,并将其中的实参1和2传入到打印函数当中,因此在这里,print_func(1,2)等同于PrintNum(1,2),输出结果为:1 2
除此之外,我们还可以控制传入函数的参数位置,例如
auto print_func_adjust = std::bind(&PrintNum, std::placeholders::_2, std::placeholders::_1);
当我们调用print_func_adjust(1,2)时,输出结果为:2 1
官方的例子
#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);
// common use case: binding a RNG with a distribution
std::default_random_engine e;
std::uniform_int_distribution<> d(0, 10);
auto rnd = std::bind(d, e); // a copy of e is stored in rnd
for(int n=0; n<10; ++n)
std::cout << rnd() << ' ';
std::cout << '\n';
// 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';
// smart pointers can be used to call members of the referenced objects, too
std::cout << f4(std::make_shared<Foo>(foo)) << '\n'
<< f4(std::make_unique<Foo>(foo)) << '\n';
}
输出结果:
2 42 1 10 7
12 12 12 4 5
1 5 0 2 0 8 2 2 10 8
100
10
10
10