bind看作一个通用的函数适配器,它接受一个可调用对象,生成一个新的可调用对象来"适应"原对象的参数列表。
它定义在头文件 functional 中。
auto newCallable = bind( callable , arg_list);
一般形式就是上面代码中的形式。(C++ primer 书中)
newCallable本身是一个可调用对象, arg_list 是一个逗号分隔的参数列表,对应给定的 callable 的参数。就是我们在调用 newCallable 时,newCallable 会调用 callable , 并传递给它 arg_list 中的参数。(书中的原话,我觉得说明得非常好,所以直接照搬过来)
void P_rint(int &x, int &y)
{
x += x;
y += y;
cout << " x = " << x<
使用 placeholders 名字:
它的形式是: _n ,它是在 arg_list 中的,它们是占位符,表示的是 newCallable 的参数 ,它们的作用就是先占位置,其中n是一个整数,eg: _1 , _2 ...
#include
using namespace std;
#include //标准库 bind 函数所在头文件
using namespace std::placeholders;//像下面这样太过于麻烦,直接定义这一个就可以用所有的了
using std::placeholders::_1;//要使用谁就像这样命名谁
using std::placeholders::_2;
void P_rint(int x, int y)
{
x += x;
y += y;
cout << " x = " << x<auto newCallable = bind( P_rint , _1 ,_2);//这个占位符的数字也是代表函数参数的位置,_1代表函数P_rint的第一个参数,依此类推
占位符的数字代表了函数的参数位置。
auto newCallable = bind( P_rint , _1 ,_2);
newCallable( 11 , 22);//输出 x 为22 , y 为44;
auto newCallable = bind( P_rint , _2 ,_1);
newCallable( 11 , 22);//输出 x 为44 , y 为22;
auto newCallable = bind( P_rint , _2 ,_2);
newCallable( 11 ,22);//输出 x 为44 , y 为44;两个都为44,前面的11对于函数是没有用的但是还是
//不能删除了因为它的参数列表不能比上面函数的参数列表少,只可以多不能少。
newCallable(1, 2, 3, 4, 5, 6, 8);//可以像这样有多个,但是数量不能低于函数的参数个数
上面的代码中占位符有一个编译器不会报错,但是调用的时候会报错。
上面我们可以知道我们可以利用 bind 重排参数顺序。
默认情况下,bind 的那些不是占位符的参数被拷贝到 bind 返回的可调用对象中。
当我们希望传递给 bind 一个对象而又不拷贝它,就要使用标准库 ref 函数,它返回一个对象,包含给定的引用,这个对象是可以拷贝的。标准库中还有一个 cref 函数,生成一个保存 const 引用的类。这两个函数也定义头文件 functional 中。
ostream& sy_1(ostream& os, const string& s, char c)
{
return os << s <<" " << c << '\n';
}
int main() {
string s("China!");
char c = 's';
auto S_y = bind(sy_1, ref(cout), _2,_3);
S_y(sy_1, s, c);
return 1028;
}
在上面的代码中我们使用了 ref 函数,不使用的话程序就会出错,原因是我们不能拷贝一个 ostream 。
阅读《C++ primer 》笔记。