bind1st bind2nd 的由来
for_each 源码来分析 传入的_Function
template
inline _LIBCPP_INLINE_VISIBILITY
_Function
for_each(_InputIterator __first, _InputIterator __last, _Function __f)
{
for (; __first != __last; ++__first)
__f(*__first);
return _VSTD::move(__f); // explicitly moved for (emulated) C++03
}
上面__f(*__first); 看得到_Function 只接受一个参数,如果有二个参数情况下怎么办? 于是有了bind1st bind2st 绑定,绑定一个参数,另一个参数就是传入的*iterator . find_if 等同理。
所谓 bind1st bind2st 参数绑定,指operator()(...)有二个参数时,指定其中一个绑定,另一个就是*iterator传入;当没有参数或只有一个参数时默认传入的就是*Iterator。所以不需要绑定。
STL 内置函数子类的用法举例
-
//移除所有小于100的元素
-
arr.erase( std::remove_if( arr.begin(), arr.end(),
-
std::bind2nd( std::less<int>(), 100)), arr.end()); //(*iterator)val1<100; operator(..)二个参数
-
// 移除所有大于100的元素
-
arr.erase( std::remove_if( arr.begin(), arr.end(),
-
std::bind1st( std::less<int>(), 100)), arr.end()); //100operator(..)二个参数
-
自定义函数子类与函数子类对象举例 effective stl 40 43
-
template<typename T>
-
class Meetsthreshold:public std::unary_function<Widget,bool>{
-
private:
-
const T threshold;
-
public:
-
MeetsThreshold(const T& threshold);
-
bool operator()(const Widget&)const; //一个参数,不需要绑定
-
....
-
};
-
-
struct WidgetNameCompare:
-
public std::binary_function<Widget,Widget,bool>{
-
bool operator()(const Widget& lhs,const Widget& rhs)const; //二个参数,需要绑一个
-
};
针对此函数子的调用
-
list<Widget>widgets;
-
list<Widget>::reverse_iterator i1 = find_if(widgets.rbegin(),widgets.rend(),not1(Meetsthreshold<int>(10)));
-
//找到最后一个不符合阈值是10 的Widget
-
-
Widget w(...);
-
list<Widget>::iterator i2 =
-
find_if(widgets.begin(),widgets.end(),bind2nd(WidgetNameCompare(),w));
bind1st bind2nd 配合 mem_fun men_fun_ref 将成员函数生成函数子类对象举例
for_each code
-
class TestClass{
-
-
public:
-
TestClass():data(0)
-
{}
-
-
void test()
-
{
-
data++;
-
}
-
private:
-
int data;
-
};
-
TestClass *p1 = new TestClass();
-
TestClass *p2 = new TestClass();
-
TestClass *p3 = new TestClass();
-
-
std::vector<TestClass*> lpw;
-
lpw.push_back(p1);
-
lpw.push_back(p2);
-
lpw.push_back(p3);
-
-
for_each(lpw.begin(),lpw.end(),std::mem_fun(&TestClass::test));
运行后,p1->data = p2->data = p3->data = 1;
find_if code
-
class TestClass1{
public:
TestClass1(int d):data(d)
{}
bool test() const
{
return data>3;
}
bool test1(int v) const
{
return data>v;
}
private:
int data;
};
TestClass1 *t1 = new TestClass1(1);
TestClass1 *t2 = new TestClass1(2);
TestClass1 *t3 = new TestClass1(4);
TestClass1 *t4 = new TestClass1(5);
std::vector lpt;
lpt.push_back(t1);
lpt.push_back(t2);
lpt.push_back(t3);
lpt.push_back(t4);
std::vector::iterator it = std::find_if(lpt.begin(),lpt.end(),std::bind2nd(std::mem_fun(&TestClass1::test1),3)); //right
运行后,p1->data = p2->data = p3->data = 1;
成员函数有参数的话,与mem_fun men_fun_ref 对接情况下,只能与bind2nd 绑定,因为第一个参数是this本身。 原理参见
http://blog.163.com/ecy_fu/blog/static/4445126200932510531455/
effective stl 40 43中的代码示例,对理解此文有很大帮助,本文引入40中的代码,未引入43中的例子。
现在一切都安静了,因为C++ 11 出来了,这些都可以用方便的lambda 函数来实现了。 参见相关博文。
阅读(1215) | 评论(0) | 转发(0) |