参数的绑定通常称为"Currying"(译注:Currying---“烹制咖喱烧菜”,此处意指对函数或函数对象进行加工修饰操作), "_1"是一个占位符对象,用于表示当函数f通过函数ff进行调用时,函数ff的第一个参数在函数f的参数列表中的位置。第一个参数称为"_1", 第二个参数为"_2",依此类推。例如:
int f(int, char, double); auto frev = bind(f, _3, _2, _1); // 翻转参数顺序 int x = frev(1.2, 'c', 7); // f(7, 'c', 1.2);
此处,auto关键字节约了我们去推断bind返回的结果类型的工作。
我们无法使用bind()绑定一个重载函数的参数,我们必须显式地指出需要绑定的重载函数的版本:
int g(int); double g(double); auto g1 = bind(g, _1); // 错误:调用哪一个g() ? auto g2 = bind( (double(*)(double))g, _1); // 正确,但是相当丑陋
void H(int a); //绑定全局函数 auto f11 = std::bind(H, std::placeholders::_1); auto的类型实际上是std::function<void(int)> //绑定带参数的成员函数 std::function<void (char*, int)> f = std::bind(&ReadHandler::ConnectPreProcess, this, std::placeholders::_1, std::placeholders::_1); //三元函数转换成一元函数 int f(int, char, double); // 绑定f()函数调用的第二个和第三个参数, // 返回一个新的函数对象为ff,它只带有一个int类型的参数 auto ff = bind(f, _1, ‘c', 1.2); int x = ff(7);
自己写代码示例如下:
int Func(int x, int y);
auto bf1 = std::bind(Func, 10, std::placeholders::_1);
bf1(20); ///< same as Func(10, 20)
int HelloWorld::AddFunc( int a, int b )
{
return a + b;
}
bool HelloWorld::init()
{
auto bf2 = std::bind(&HelloWorld::AddFunc,this , std::placeholders::_1, std::placeholders::_2 );
auto result1 = bf2(10, 20); ///< same as a.Func(10, 20)
std::function< int(int)> bf3 = std::bind(&HelloWorld::AddFunc, this, std::placeholders::_1, 100);
auto result2 = bf3(10); ///< same as a.Func(10, 100)
}
上面的例子中,bf1是把一个两个参数普通函数的第一个参数绑定为10,生成了一个新的一个参数的可调用实体体; bf2是把一个类成员函数绑定了类对象,生成了一个像普通函数一样的新的可调用实体; bf3是把类成员函数绑定了类对象和第二个参数,生成了一个新的std::function对象。看懂了上面的例子,下面我们来说说使用bind需要注意的一些事项:
(1)bind预先绑定的参数需要传具体的变量或值进去,对于预先绑定的参数,是pass-by-value的
(2)对于不事先绑定的参数,需要传std::placeholders进去,从_1开始,依次递增。placeholder是pass-by-reference的
(3)bind的返回值是可调用实体,可以直接赋给std::function对象
(4)对于绑定的指针、引用类型的参数,使用者需要保证在可调用实体调用之前,这些参数是可用的










