1.2 函数对象
我将介绍STL使用的一些基本的技术,它会让你了解:在普通C++机制上建立的STL是如何提供空前的灵活性和性能的。迄今为止,我们所描述的STL框架组件都有些严格。每种算法都严格地采用标准指定的方法来准确地实现某种功能。例如,我们需要查找一个与自己指定的值相等的元素。实际上,查找一个带有某些(自己指定的)属性的元素,例如小于某个给定的值、匹配某个并非简单相等的值(例如,匹配大小写无关的字符串或者在允许很小差别的情况下,匹配双精度数值),是一项很普通的事务。
下面的例子不是查找值7,我们将查找某些符合条件的值(也就是小于7的值):
vector::iterator p = find_if(v.begin(),v.end(),Less_than(7));
if (p != vi.end()) {
// 我们找到了值小于7 的元素
// …
}
else {
// vi 没有值小于 7 的元素
// …
}
Less_than(7)是什么东西呢?它是一个函数对象,它是某个类的对象,该类带有应用程序操作符(( )),被定义成执行某个函数:
template struct Less_than {
T value;
Less_than(const T& v) :value(v) { }
bool operator()(const T& v) const { return v
例如:
Less_than f(3.14); // Less_than 保存了双精度值 3.14
bool b1 = f(3); // b1 为真(3<3.14 是真的)
bool b2 = f(4); // b2 为假(4<3.14 是假的)
从2004年的情况来看,在D&E中没有提到函数对象是很奇怪的。我们应该使用一个章节来讲述它们。甚至于用户自定义的应用程序操作符(( ))的使用情况也没有提到,尽管它已经存在很长时间,并且很卓著。例如,它是几个最初的允许重载的操作符之一(在=之后),它还用于模仿Fortran下标(subscript notation)。
我们可以编写一个find()版本,它使用了函数对象,而不是简单的!=来检测是否可以找到某个元素。它的名字是find_if():
template
In find_if(In first, In last, Pred pred)
{
while (first!=last && !pred(*first)) ++first;
return first;
}
我们简单地用!pred(*first)代替了*first!=val。函数模板find_if()会接受任何能够把元素值作为参数调用的对象。特别地,我们可以把普通的函数作为它的第三个参数来调用find_if():
bool less_than_7(int a)
{
return 7::iterator p = find_if(v.begin(),v.end(),less_than_7);
但是,这个例子显示了,与函数相比我们为什么更喜欢函数对象:我们可以使用一个(或多个)参数来初始化函数对象,同时函数对象可以保持这些信息供以后使用。函数对象可以保持任何状态。这样就可以形成更通用、更优良的代码。如果我们需要,我们以后可以检查它的状态。例如:
文章来源于领测软件测试网 https://www.ltesting.net/