标签:lap cto std 相同 bin auto 方法 分享 sse
1、bind1st和bind2end
bind1st和bind2end是C++中的函数绑定器,它可以将一个变量绑定至一个二元函数对象,从而获得一个一元函数对象。使用需要包含头文件<functional>
比如我们使用find_if()查找容器中大于100的元素,使用函数和函数对象的方法是如下:
bool GreaterThan(const int& i)
{
return i > 100;
}
class CGreaterThan
{
public:
bool operator()(const int&i)
{
return i > 100;
}
};
int main()
{
vector<int> v = list_of(5) (2) (101) (3);
auto iter = find_if(v.begin(), v.end(), /*GreaterThan*/CGreaterThan());
if (iter != v.end())
cout << *iter << endl;
return 0;
}
而使用函数绑定器的话就不用我们自定义函数或函数对象,如下所示:
#include <functional> int main() { vector<int> v = list_of(5) (2) (101) (3); int x = 100; auto iter = find_if(v.begin(), v.end(), bind2nd(greater<int>(), x)); if (iter != v.end()) cout << *iter << endl; return 0; }
上面的bind2nd()将值100绑定到二元谓词greater<int>()的第二个参数,相当于将greater<int>()的第二个参数直接替换成了100,如果使用bind1st()的话就是将值绑定到第一个参数。
not1和not2可以用来做否定值(not1是否定返回值是单目的函数,std中还有not2它是否定返回值是双目的函数),如以下就是获得小于等于100的元素:
int main()
{
vector<int> v = list_of(5) (2) (101) (3);
auto iter = find_if(v.begin(), v.end(), not1(bind2nd(greater<int>(), 100)));
if (iter != v.end())
cout << *iter << endl;
return 0;
}
2、bind
boost中的bind是bind1st/bind2nd的增强版,它也会返回一个函数对象,由于函数对象中重载了(),所以可以像函数一样来使用函数对象。bind()的第一个参数必须是一个可调用对象,比如函数、函数指针、函数对象,之后它最多接受九个参数。占位符用来表示使用哪一个参数。bind位于头文件"boost/bind.hpp"中。
①、绑定普通函数
#include "boost/bind.hpp" int func(int a, int b) { return b * b; } int main() { int x = 5, y = 10, z = 15; bind(func, x, y); //获得一个无参仿函数:绑定x到func第一个参数,绑定y到func第二个参数。bind(func, x, y)()相当与调用func(x, y) bind(func, x, _1); //获得带一个参数的仿函数:绑定x到func第一个参数,func第二个参数使用仿函数的第一个参数。bind(func, x, _1)(y)相当与func(x, y) bind(func, _1, y); //获得带一个参数的仿函数:绑定y到func第二个参数,func第一个参数使用仿函数的第一个参数。bind(func, _1, y)(x)相当与func(x, y) bind(func, _2, _1); //获得带两个参数的仿函数,func的第一个参数使用仿函数的第二个参数,func的第二个参数使用仿函数的第一个参数。bind(func, _2, _1)(x, y)相当于func(y, x) bind(func, x, _2); //获得带一个参数的仿函数:绑定x到func第一个参数,func第二个参数使用仿函数的第二个参数。bind(func, x, _2)(z, y)相当与func(x, y),参数z被忽略 bind(func, _2, y); //获得带一个参数的仿函数:绑定y到func第二个参数,func第一个参数使用仿函数的第二个参数。bind(func, _2, y)(z, x)相当与func(x, y),参数z被忽略 return 0; }
②、绑定函数指针
bind绑定函数指针与绑定普通函数方法相同。
③、绑定类的成员函数
bind绑定类的public成员函数可以用来配合STL算法来操作容器中的对象,以下是使用bind与不使用bind完成对容器for_each()操作的比较:
#include "boost/bind.hpp"
class CMyClass
{
public:
void print()
{
cout << m_Value1 << ", " << m_Value2 << endl;
}
private:
int m_Value1 = 0, m_Value2 = 0;
};
void Print(CMyClass& c)
{
c.print();
}
int main()
{
vector<CMyClass> v(10);
for_each(v.begin(), v.end(), /*Print*/bind(&CMyClass::print, _1));
return 0;
}
④、绑定类的成员变量
bind还可以绑定类的public成员函数,同样配合STL算法来操作容器中的元素,以下是使用bind与不使用bind完成对容器transform()操作的比较:
#include "boost/bind.hpp" class CPoint { public: int x = -1; int y = -1; }; int assign(CPoint point) { return point.x; } int main() { vector<CPoint> inputV(10); vector<int> outputV(10); transform(inputV.begin(), inputV.end(), outputV.begin(), /*assign*/bind(&CPoint::x, _1)); for (auto iter = outputV.begin(); iter != outputV.end(); iter++) cout << *iter << endl; return 0; }
⑤、绑定函数对象
bind绑定函数对象的时候需要在被绑定类中使用typedef来定义operator()返回值类型为result_type,否则在bind的时候还需使用<type>来指定类型。下面为使用count_if()算法来查找容器中元素长度小于5的个数,而count_if()使用的仿函数类型中
只有一个参数,可以使用两种方法来实现长度参数的传递:一种是将长度作为仿函数的构造函数的参数传入,一种是使用bind来获得一个参数的仿函数:
#include "boost/bind.hpp" class CLengthShorterThan { public: CLengthShorterThan(int len):m_len(len){} bool operator()(const string& str) { return str.length() < m_len; } private: int m_len; }; class CLenShorterThan { public: bool operator() (const string& str, int len) { return str.length() < len; } typedef bool result_type; }; int main() { vector<string> myVector = list_of("c++") ("c#") ("python"); int len = 5; int count = count_if(myVector.begin(), myVector.end(), /*CLengthShorterThan(len)*/bind(CLenShorterThan(), _1, len)); return 0; }
bind也可以绑定预定义的函数对象,如less<>、greater<>等。还可以使用BOOST_AUTO来存储bind表达式的结果,即保存bind返回的函数对象,以便使用。function库也可以存储bind表达式的结果。
#include "boost/bind.hpp"
#include "boost/typeof/typeof.hpp"
int main()
{
BOOST_AUTO(funObj, bind(greater<int>(), _1, _2));
assert(funObj(2, 1));
return 0;
}
标签:lap cto std 相同 bin auto 方法 分享 sse
原文地址:http://www.cnblogs.com/milanleon/p/7491180.html