STL源码剖析之仿函数简介
2011-06-29 21:33 Aga.J 阅读(835) 评论(0) 编辑 收藏 举报1 仿函数也称为函数对象,是一种具有函数特质的对象。调用者可以像函数一样的使用这些对象,例如在很多STL算法中,都可以看到,我们可以将一个方法作为模板内的参数传入到算法实现中,例如sort的时候我们可以根据我们传入的自定义的compare函数来进行比较排序。解决办法是使用函数指针,或者是将这个“操作”设计为一个所谓的仿函数,再用这个仿函数生成一个对象,并用这个对象作为算法的一个参数。
2 那为什么STL不使用函数指针而使用仿函数呢,因为函数指针不能满足STL对抽象性的要求,无法和STL的其他组件搭配以产生更加灵活的效果。
3 怎样实现这样一个仿函数呢?(可以直接使用对象名来使用函数)?答:我们必须自定义或者重载函数调用的运算符operator (),先产生类对象的一个匿名对象,再调用相应的函数。
4 STL仿函数应该有能力被函数适配器修饰,就像积木一样串接,然而,为了拥有配接能力,每个仿函数都必须定义自己的associative types(主要用来表示函数参数类型和返回值类型),就想迭代器如果要融入整个STL大家庭,也必须按照规定定义自己的5个相应的类型一样,这些assocaiative type是为了让配接器可以取得仿函数的某些信息,当然,这些associative type都只是一些typedef,所有必要操作在编译器就全部完成了,对程序的执行效率没有任何影响,不会带来额外的负担。
5 unary_function
用来呈现一元函数的参数类型和返回值类型
Template<class Arg, class Result>
Struct unary_function
{
Typedef Arg argument_type;
Typedef Result result_type;
}
//自定义的一元仿函数可以继承上类来获得类型定义
Template<class T>
Struct negate:public unary_function<T,T>
{
T operator()(const T& x)const {return –x;}
};
6 binary_function
用来呈现二元函数的第一个参数类型,第二个参数类型,和返回值类型
Template<class Arg1, class Arg2, class Result>
Struct binary_function
{
Typedef Arg1 first_argument_type;
Typedef Arg2 second_argument_type;
Typedef Result result_type;
};
//use
Template<class T>
Struct plus: public binary_function<T,T,T>
{
T operator()(const T& x, const T& y)const {return x+y ;}
};
//适配器 前瞻(后文会介绍),使用组合而不是继承
Template<class Operation>
Class binder1st
{
Protected:
Operation op;
Typename Operation:first_argument_type value;
Public:
Typename Operation::result type operation() ( const typename Operation::second_argument_type& x)const;
} ;
7 STL内建的“算术类仿函数”,支持 加法,减法,乘法,除法,模数,否定
使用:
#include<iostream>
#include<functional>
Using namespace std ;
Int main()
{
Plus<int> plusobj;
Cout<<plusobj(3,5)<<endl;
Cout<<plus<int>(3,5)<<endl;
// accumulate( iv.begin(), iv.begin(),1 , multiplies<int>());
}
8 STL内建的关系运算仿函数支持 等于,不等于,大于,大于等于,小于,小于等于
// use
#include<iostream>
#include<functional>
Using namespace std;
Int main()
{
Equal_to<int> qual_to_obj;
Cout<equal_to_obj(3,5)<<endl;
Cout<<equal_to<int>(3,5)<<endl;
// sort ( iv.begin(), iv.end(), greater<int>());
}
9 STL内建支持 逻辑运算仿函数, and or not
//use
#include<iostream>
#include<functional>
Using namespace std;
Int main()
{
Logical_and<int> and_obj; //注意这里的参数类是int
Cout<<and_obj(true, true)<<endl;
Cout<<logical_and<int>(true,true)<<endl;
}
作者:Aga.J
出处:http://www.cnblogs.com/aga-j
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
个人学习笔记仅供本人记录知识所用,不属发表性文章。