# 十、STL函数对象---函数对象的概念

xiaoxiao2021-02-28  80

标签(空格分隔): c++STL


Function object的概念

就是一个定义了operator()的对象;

class FunctionOjbectType{ public: void operator()(){ //statements } }; FunctionObjectType fo; fo(); //调用的fo对象的operator()

优点:

function object 比一般函数灵巧,可以拥有状态;同样的函数对象类可以拥有不同的实例;每个函数对象由类型;因此可以将函数对象的类型当做模板参数传递;容器也可以因为不同的函数对象不同而不同;执行速度上,函数对象比函数指针快;

1 以函数对象为排序准则

例如:使用函数对象类为容器排序;

template < class T, // set::key_type/value_type class Compare = less<T>, // set::key_compare/value_compare class Alloc = allocator<T> // set::allocator_type > class set;

set容器提供默认排序为less<T>类,可以自定义:

class FunctionOjbectType{ public: void operator()(){ //statements } }; set<Myclass, FunctionObjectType> p; //函数对象为排序规则

2 FUnction object 拥有内部状态

通过给函数对象传递参数改变状态:

值传递引用传递 传递参数都是通过构造函数传递; class FunctionOjbectType{ public: FunctionOjbectType(Args .. args){ //statements } void operator()(){ //statements } };

3 for_each()的返回值

for_each可以传回其函数对象,因此可以通过for_each的返回值获取函数对象的状态;

template<class InputIterator, class Function> Function for_each(InputIterator first, InputIterator last, Function fn) { while (first!=last) { fn (*first); ++first; } return fn; // or, since C++11: return move(fn); }

例子:

class MeanValue{ public: int num; int sum; MeanValue():num(0),sum(0){} void operator()(int elem){ ++num; sum += elem; } double value(){ return static_cast<double>(sum)/static_cast<double>(num); } }; //-----------省略-------------- vector<int> v={1,2,3,4,5,6}; MeanValue mv = for_each(v.begin(),v.end(),MeanValue());

4 predicate (判断式)和function object(函数对象)

predictate: 返回boolean值的函数或者函数对象对stl而言,并非所有boolean值的函数都是合法的predictate; 例子: class rm{ public: int count; int nth; rm(int n) :count(0), nth(n){ } bool operator()(int n){ return ++count == nth; } }; //--------------省略---------- vector<int> v = {1,2,3,4,5,6,7,8,9}; vector<int>::iterator it,iter; it = remove_if(v.begin(), v.end(), rm(3)); for (iter = v.begin(); iter != it; ++iter) cout << *iter<<" ";

结果为:

1 2 4 5 7 8 9

缺少了3和6; 原因:

template<typename ForwIter, typename Predicate> ForwIter remove_if(ForwIter beg, ForwIter end,Predicate op) { beg = find_if(beg,end,op); if(beg==end) return beg; else{ ForwIter next = beg; return remove_copy_if(++next,end,beg,op); } }

这个算法使用find_if查找被移除的第一个元素,然后,使用传入的predicate处理剩下的元素,这个时候原始的Nth再次被使用;就会移除第六个元素;

【注意:】为了考虑不该依赖任何实现细节,应该总是将predicate的operator()声明为const成员函数;

转载请注明原文地址: https://www.6miu.com/read-78122.html

最新回复(0)