电大网上作业代做网站,规模以上工业企业认定标准,免费广告语设计生成器,做网站的时候遇到的问题STL中有一个叫做“适配器”的概念#xff0c;它指的是某些函数可能定义了两个形参#xff0c;但是某些算法需要的函数却有时候需要一个形参#xff0c;那么就需要对其进行适配#xff0c;将原本只需要两个参数的函数转变成需要1和参数就能正常运行的函数。就像你为你的笔记…STL中有一个叫做“适配器”的概念它指的是某些函数可能定义了两个形参但是某些算法需要的函数却有时候需要一个形参那么就需要对其进行适配将原本只需要两个参数的函数转变成需要1和参数就能正常运行的函数。就像你为你的笔记本充电能直接一根火线一根零线直接接在你的电脑上吗肯定也是需要一个适配器将国内标准电压转化成笔记本需要的额定电压。“适配器”就是由此而来。
std::binary_function
关于类 binary_function 的定义很简单源码如下
template class _Arg1, class _Arg2, class _Result
struct binary_function
{ // base class for binary functionstypedef _Arg1 first_argument_type;typedef _Arg2 second_argument_type;typedef _Result result_type;
};这是一个二元函数的模板类定义两个输入参数一个返回值。我们如果想让我们自己写的仿函数支持适配器那么就必须从binary_function派生出来。
#include iostream
#include functionaltemplatetypename T
class MLess : public std::binary_functionT, T, bool
{
public:bool operator() (const T a, const T b) const{return a b;}
};std::binary_functionT, T, bool 前两个参数分别表示第一第二个参数bool表示operator的返回值。做完这些准备工作就可以使用std::bind1st、std::bind2nd来进行适配了。
std::bind1st、std::bind2nd bind1st 是将一个二元函数的第一个参数绑定为固定值的函数实质上是仿函数类bind2nd 是将一个二元函数的第二个参数绑定为固定值的函数实质上是仿函数类 他们再使用的时候都需要加上头文件 关于bind1st的实现也很简单
template class _Fn2
class binder1st : public unary_functiontypename _Fn2::second_argument_type, typename _Fn2::result_type
{ // functor adapter _Func(stored, right)
public:typedef unary_functiontypename _Fn2::second_argument_type, typename _Fn2::result_type _Base;typedef typename _Base::argument_type argument_type;typedef typename _Base::result_type result_type;binder1st(const _Fn2 _Func, const typename _Fn2::first_argument_type _Left) : op(_Func), value(_Left){ // construct from functor and left operand}result_type operator()(const argument_type _Right) const{ // apply functor to operandsreturn (op(value, _Right));}result_type operator()(argument_type _Right) const{ // apply functor to operandsreturn (op(value, _Right));}protected:_Fn2 op; // the functor to applytypename _Fn2::first_argument_type value; // the left operand
};// TEMPLATE FUNCTION bind1st
template class _Fn2, class _Ty
inline binder1st_Fn2 bind1st(const _Fn2 _Func, const _Ty _Left)
{ // return a binder1st functor adaptertypename _Fn2::first_argument_type _Val(_Left);return (binder1st_Fn2(_Func, _Val));
}从代码中可以看出bind1st 是一个函数模板需要传入两个参数_Func 和 _Left binder1st 是一个仿函数类构造函数中将 _Func 赋值给了成员 op _Left 赋值给我成员 value重载的 () 正好调用的函数 op(value, _Right)。
如何使用bind1st呢
auto lessObj std::bind1st(MLessint(), 5);//实际上是返回一个新的函数对象 binder1st 成员 op 为 MLessint() 对象 value 为 5这里就是将5绑定到MLess的第一个参数中即
bool operator() (const T b) const{return 5 b;}即
result_type operator()(const argument_type _Right) const
{ // apply functor to operandsreturn (op(value, _Right));
}同理bind2nd也是这样
#include iostream
#include functional
#include algorithm
#include listtemplatetypename T
class MTestClass : public std::binary_functionT, T, void
{
public:void operator() (const T a, const T b) const{if (a b)std::cout a std::endl;}
};int main(int argc, char** argv)
{std::listint nList;nList.push_back(10);nList.push_back(20);nList.push_back(30);nList.push_back(40);nList.push_back(50);nList.push_back(60);std::for_each(nList.begin(), nList.end(), std::bind2nd(MTestClassint(), 30));system(pause);return 0;
}std::bind
提起std::bind可能你一下子就感觉熟悉不少对这个适配器应该比前面两个更“知名”一些它提供的功能也完全覆盖了前两个适配器例如如果我们不使用std::bind1st、std::bind2nd我们完全可以这么写 int res count_if(coll.begin(), coll.end(), std::bind(lessint(), 10, std::placeholders::_1)); // bind1st(lessint(), 10));int res count_if(coll.begin(), coll.end(), std::bind(lessint(),std::placeholders::_1, 10)); // bind2st(lessint(), 10));