一些STL算法要求我们使用一元函数,可是有些函数却不是一元的,C++提供了一项叫做函数绑定的技术
顾名思义,就是讲参数绑定到函数上,使一些非一元函数能够当作一元函数使用,准确的来说,不是哪些非一元函数本身能当做一元函数使用,而是一个名为bind的函数包装器能返回一个绑定过参数的函数对象。
bind是一个函数,也是一个函数包装器,定义在<functional>头文件中
简单的参数绑定
假设搜索第一个大于长度n的字符串,可以用find_if,但是其接受一个一元谓词,那就可以用bind包装函数将其变为一元谓词
演示
bool Find(const string &s,int a)
{
return s.size()>=a;
}
int main()
{
vector<string> vec {"hello","english","aaa","yes","C++"};
auto i = find_if(vec.begin(), vec.end(),bind(Find,placeholders::_1,6));
cout << *i;
}
运行结果
english
bind(Find,placeholders::_1,6)
其中_1是一个占位参数,从1开始_n,说明了被包装过的函数对应传入到原来函数参数的顺序
被定义在名称空间placeholders中,placeholders又被包含在namespace中,但如果不使用using声明还是要使用作用域解析符号来使用。
使用方法
#include <bits/stdc++.h>
using namespace std;
//降序排列
bool is_Swap(const string & s1,const string & s2)
{
return s1<s2;
}
int main()
{
vector<string> vec {"hello","english","aaa","yes","C++"};
sort(vec.begin(), vec.end(),bind(is_Swap,placeholders::_2,placeholders::_1));
for_each(vec.begin(), vec.end(),[](const string &s){cout << s << endl; });
}
很容易发现bind函数是一个可变参数函数
主要作用就是讲函数进行包装以满足一些STL算法的需求。
有时候一些特殊的对象不能赋值,比如流对象。要用到ref或者cref函数,返回一个对象,包含给定的引用,此引用时可复制的。
ostream & print(ostream & os, const string & s,const char ch)
{
cout << s << ch;
return os;
}
int main()
{
vector<string> vec {"hello","english","aaa","yes","C++"};
for_each(vec.begin(), vec.end(),bind(print,ref(cout),placeholders::_1,'\n'));
}