函数对象小记

函数对象就是一个实现了operator()的类。

正是因为实现了operator()操作符,所以在使用的时候,可以调用 ()操作符,看起来就像是对一个函数的调用,但是实际上这是一个对象。所以称之为函数对象。

 

普通函数 vs 函数对象类

 //普通函数
void WhoMakesMeAngry(string name)
{
    std::cout << name << "made me angry" << std::endl;
}

 //函数对象类
class FunctionObjectDefine
{
     public:
        void operator()(string name) { std::cout << name << "made me angry" << std::endl;};
};

int main()
{
    WhoMakesMeAngry("taz")
    
    FunctionObjectDefine func;
    func("taz")//和普通函数 WhoMakesMeAngry("taz")调用方式一样
    
    return 0;
}

上述这个例子中,函数对象并没有存内部状态,即没有数据成员,那用直接用函数好了呀。

函数对象的特殊作用就是可以实现携带附加数据,而普通函数不行。

函数对象在STL中作为参数使用

1.std::generate_n 中的 Generator生成器

template <class OutputIterator, class Size, class Generator>
  void generate_n ( OutputIterator first, Size n, Generator gen )
{
  while (n>0) {
    *first = gen();
    ++first; --n;
  }
}

其中第三个参数 Generateor,传入的就是一个函数对象或者是函数指针,类型是无参数的输入,返回是符合*first类型的值。下面例子分别用函数对象和函数指针来作为参数传入:

 //储存了内部状态的函数对象 m_origin
class SuccessiveNumFunObject
{
	public:
		SuccessiveNumFunObject(int origin = 0):m_origin(origin){}
		int operator() ()
		{
			return m_origin++;
		}
	private:
		int m_origin;
};
 //普通函数,对全局函数的操作
int current = 3;
int SuccessiveNumFun () { return current++; }

vector<int> dest;
// 传入的参数是实例化的函数对象(3给函数对象的内部状态赋初值)
generate_n(back_inserter(dest),10,SuccessiveNumFunObject(3));

// 传入的参数是函数指针(函数名就可以表示函数指针)
// generate_n(back_inserter(dest),10,SuccessiveNumFun);

2.std::find_if 中的UnaryPredicate一元谓词函数

template<class InputIterator, class UnaryPredicate>
  InputIterator find_if (InputIterator first, InputIterator last, UnaryPredicate pred)
{
  while (first!=last) {
    if (pred(*first)) return first;
    ++first;
  }
  return last;
}

同样,第三个参数需要传入函数对象或函数指针,从实现中可以看出,需要的是一个输入参数-*first类型,返回的是bool值。

下面的例子中,没有用到输入的参数。

// 函数对象类
class NthFunObject
{
    public:
       NthFunObject(int n=0):m_nth(n),m_count(1){}
       bool operator() (int)
       {
           return m_count++ == m_nth;
       }
		
       int GetCount()const
       {
           return m_count;
       }
		
    private:
       int m_nth;
       int m_count;
};
NthFunObject nth(3);
//dest内容为连续数字:3,4,5,6,……,12
vector<int>::iterator nthItr = find_if(dest.begin(),dest.end(),nth);  
std::cout << "The 3rd value of dest is " << *nthItr << '\n';

// 函数指针
int gNth = 3;
int gCount = 1;
bool NthFun (int i) {
  return (gNth==gCount++);
}

nthItr = std::find_if (dest.begin(), dest.end(), NthFun);
std::cout << "The 3rd value of dest is " << *nthItr << '\n';

类似的,remove_if第三个参数也是一元谓词函数。remove_if  所谓的remove只是概念上的remove:

扫描二维码关注公众号,回复: 6060848 查看本文章

1,2,3,4,5,6,7,8,9,10 ---->   remove_if 为3   ---->1,2,4,5,6,7,8,9,10,10.

算法库绝不改变容器的大小!

3.std::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);
}

 需要的是一个输入参数-*first类型,返回类型无所谓。for_each就是对每个元素进行一些操作。

void myfunction (int i) {  // function:
  std::cout << ' ' << i;
}

struct myclass {           // function object type:
  void operator() (int i) {std::cout << ' ' << i;}
} myobject;


std::cout << "dest contains:";
for_each (dest.begin(), dest.end(), myfunction);
std::cout << '\n';

// or:
std::cout << "dest contains:";
for_each (dest.begin(), dest.end(), myobject);
std::cout << '\n';

STL中的一些函数对象

modulus<T>

取模函数对象

template <class T> struct modulus : binary_function <T,T,T> {
  T operator() (const T& x, const T& y) const {return x%y;}
};

greater<T>

比较第一个参数是否大于第二个参数

template <class T> struct greater : binary_function <T,T,bool> {
  bool operator() (const T& x, const T& y) const {return x>y;}
};
// 降序排列 50 40 30 20 10
int numbers[]={20,40,50,10,30};
std::sort (numbers, numbers+5, std::greater<int>());

less<T>

比较第一个参数是否小于第二个参数

template <class T> struct less : binary_function <T,T,bool> {
  bool operator() (const T& x, const T& y) const {return x<y;}
}

logical_and<T>

逻辑与函数对象

template <class T> struct logical_and : binary_function <T,T,bool> {
  bool operator() (const T& x, const T& y) const {return x&&y;}
};

猜你喜欢

转载自blog.csdn.net/u012138730/article/details/88659319
今日推荐