C++标准库bind函数知一二

对可调用对象(函数指针,仿函数,lambda表达式等)进行参数绑定,C++11提供了名为bind的标准库函数,它定义在头文件functional中。

bind函数可以看作是一个通用的函数适配器,它可以接受一个可调用对象,生成一个新的可调用对象来"适应"原对象的参数列表

调用bind的一般形式为:auto newCallable = bind(callable, arg_list)
其中,newCallable本身是一个可调用对象,arg_list是一个逗号分隔的参数列表(形如arg1,arg2,arg3,…),对应给定的callable的参数。

当我们调用newCallable时,newCallabele会调用 callable,并传递给它arg_list中参数。

arg_list中的可能存在形如_n(n为自然整数)的占位符,这些占位符表示newCallable的参数,它们占据了传递给newCallable的参数的“位置”。
例如 _1为newCallable的第一个参数,_2为第二个参数,以此类推。

note:名字_n都定义在一个名为placeholders的命名空间中,而这个命名空间本身又定义在std命名空间中,所有需要先声明才能使用。
可以使用以下几种声明:
1、using std::placeholders::_n; //n为1 2 3 4 5 …
2、using namespace std::placeholders; //推荐

看了这么多文字,相信你和我一样一头雾水,让我们来看个简单的例子:

bool findstr(const string &str,string::size_type length){
	return str.size()<length;
}
//str5是一个新的可调用对象,接受一个constr string &或者string &类型参数
auto str5=bind(findstr,_1,5);

string s1("China");
string s2("Chinese");
//str5(s1)会调用findstr(s1,5),返回false
auto result1 = str5(s1)
//str5(s2)会调用findstr(s2,5),返回false
auto result2 = str5(s2)

看完例子再结合上面描述是不是感觉豁然开朗呢,bind也不过如此,哈哈哈,别急,下面还有。
就这?
除此之外,bind函数还可以将参数重新安排顺序,例如f是一个可调用对象,它有5个参数,则下面对bind的调用:

//f接受5个参数
void f(a,b,c,d,e);
//生成新的可调用对象,它有三个参数,分别用占位符_3,_2,_1表示
auto g = bind(f,a,_3,b,_1,_2);
//相当于调用f(a,Z,b,X,Y)
g(X,Y,Z);

默认情况下,bind采用值传递的方式,当我们希望以引用方式传递或者绑定的参数的类型无法拷贝时,则必须使用标准库ref函数,该函数可以生成一个引用,而cref函数生成一个const引用,两函数都定义在头文件functional

ostream &print(const string &s,ostream &out){
	out<<s;
	return out;
}
//错误,ostream类对象不允许拷贝
auto pr=bind(print,_1,cout);
//正确的做法
auto pr=bind(print,_1,ref(cout));
pr("China")<<endl;

本文到此结束,感谢您的阅读,如果觉得有帮助可以点个赞吖~
在这里插入图片描述

原创文章 7 获赞 7 访问量 344

猜你喜欢

转载自blog.csdn.net/Love_Point/article/details/105534966