仿函数与临时对象
来源:互联网 发布:ubuntu 卸载apache2 编辑:程序博客网 时间:2024/06/08 16:42
仿函数(functor),就是使一个类的使用看上去象一个函数。其实现就是类中实现一个operator(),这个类就有了类似函数的行为,就是一个仿函数类了。
所谓临时变量,就是一种无名对象。有的时候可以制造一些临时对象,可以使程序干净清爽。可以制造临时对象的方法是,在类别名称之后直接加一对小括号,并可指定初值,其意义相当于调用相应的constructor且不指定对象名称。STL最常将此技巧应用于仿函数与算法的搭配上。
见下面例子:
#include <iostream> #include <algorithm>#include <vector>using namespace std;template<typename T>class print{public:void operator()(const T&elem) //重载(){cout << elem << " ";}};int main(){int ia[6] = { 0, 1, 2, 3, 4, 5 };vector<int> iv(ia,ia+6);for_each(iv.begin(), iv.end(), print<int>());cout << endl;}
下面比较使用一般函数和使用仿函数:
#include<iostream>#include<vector>#include<algorithm>#include<iterator>using namespace std;template<class T>inline void PRINT_ELEMENTS(const T& coll,const char * optcstr=""){typename T::const_iterator pos;cout<<optcstr;for(pos=coll.begin();pos!=coll.end();++pos){cout<<*pos<<" ";}cout<<endl;}int square(int value){return value*value;}template<int theValue>void add(int &elem){elem+=theValue;}int main(){vector<int> coll1;vector<int> coll2;for(int i=1;i<=9;i++){coll1.push_back(i);}PRINT_ELEMENTS(coll1,"initialized: ");for_each(coll1.begin(),coll1.end(),add<10>);PRINT_ELEMENTS(coll1,"after adding 10: ");transform(coll1.begin(),coll1.end(),back_inserter(coll2),square);PRINT_ELEMENTS(coll2,"squared: ");system("pause");return 0;}
#include<iostream>#include<list>#include<algorithm>using namespace std;template<class T>inline void PRINT_ELEMENTS(const T& coll,const char * optcstr=""){typename T::const_iterator pos;cout<<optcstr;for(pos=coll.begin();pos!=coll.end();++pos){cout<<*pos<<" ";}cout<<endl;}class AddValue{private:int theValue;public:AddValue(int v):theValue(v) {}void operator()(int &elem) const{elem+=theValue;}};int main(){list<int> coll;for(int i=1;i<=9;i++){coll.push_back(i);}PRINT_ELEMENTS(coll,"initialized: ");for_each(coll.begin(),coll.end(),AddValue(10));PRINT_ELEMENTS(coll,"after adding 10: ");for_each(coll.begin(),coll.end(),AddValue(*coll.begin()));PRINT_ELEMENTS(coll,"after adding first element: ");system("pause");return 0;}
凡是行为像函数,那么这个对象就是函数。仿函数就是这个意思,但是STL中为什么要用仿函数而不直接用函数呢?
首先STL是一个有自己规则的框架,函数指针无法和STL其他组件搭配(配接器),产生更灵活的变化:
仿函数应当有能力被函数配接器修饰,然后彼此合作形成一个整体。为了可配接仿函数需要定义自己的相应型别(和迭代器的型别的作用是一个含义)。由于STL只使用一元和二元仿函数,所以定义了两个class:unaru_function和binary_function。这两个类没有成员,只有一些型别定义。任何仿函数,只要依个人需求选择继承其中一个class,便自动拥有了那些相应型别,也就自动拥有了配接能力。
其次仿函数相对于函数指针有其自身优点:
1、 仿函数是智能型函数
就好比智能指针的行为像指针,其就可看作是一个指针。但是智能指针是定义的一个类对象,所以在具备指针功能的同时也有其他的能力。仿函数的能力也可以超越operator()。因为仿函数可以拥有成员函数和成员变量,这意味着仿函数拥有状态。另一个好处是可以在执行期初始化它们。
2、 仿函数都有自己的型别
这就是泛型编程编写仿函数。
3、 仿函数通常比一般函数快
就template的概念而言,由于更多细节在编译器就已确定,所以通常可能进行更好的最佳化。
- 仿函数与临时对象
- 临时对象与拷贝构造函数
- 临时对象与拷贝构造函数
- 临时对象的(构造函数与析构函数)
- 函数中的临时对象
- STL源码分析--仿函数 & 模板的模板参数 & 临时对象
- 临时对象的产生和运用以及仿函数的用法
- 函数对象/仿函数
- 函数对象/仿函数
- 函数对象/仿函数
- 函数对象/仿函数
- 函数对象、仿函数
- 函数指针、函数对象、仿函数比较与入门
- 函数指针、函数对象、仿函数比较与入门
- 【题目】C++拷贝构造函数与C++临时对象
- 【翠字营原创】: C++ 临时对象分析小结 涉及函数参数值传递、函数返回值、仿函数
- 25 仿函数与函数对象(学自Boolean)
- [STL]函数对象/仿函数
- PL/SQL查询oracle数据库对象
- 我的投资案例(3)-看好互联网和金融两大朝阳行业,参投入股垂直金融招聘平台"职业梦CareerDream.cn"
- 十三、Maven快照
- HTTP协议详解
- HTML & CSS
- 仿函数与临时对象
- js字符串正则替换
- Apache Storm 学习:Supervisor,Worker,Executor,Task
- Tcpdump 和 Wireshark 的结合使用(一)
- 数字图像处理领域的二十四个典型算法及vc实现、第一章
- Javascript中null和undefined的区别
- HDU 2433 - Travel
- 旭说数据结构之二叉查找树
- sql server T-SQL 基础