函数对象(functional)
如果f是一个function object,则可以将operator()作用于f身上。他是一个行为类似于函数的对象,为了能够行为类似函数,其类别中必须定义(或重载、重写)function call运算符(operator()),就可以在函数对象后加一对小括号以此来调用函数对象定义的operator()。
调用函数对象时构造函数和operator()执行顺序
- 首先执行构造函数,构造出一个匿名对象
- 然后在执行operator(),产生函数行为
- #include <iostream>
- #include <vector>
- #include <algorithm>
- #include <string.h>
- #include <iterator>
- using namespace std;
- class F1
- {
- public:
- F1(string t):s1(t)
- {
- cout<<" 带参构造函数"<<endl;
- }
- F1()
- {
- cout<<" 无参构造函数"<<endl;
- }
- bool operator()(string s)
- {
- cout<<" operator()函数"<<endl;
- return strcmp(s.c_str(),s1.c_str());
- }
- private:
- string s1;
- };
- int main()
- {
- vector<string> vs{"hello"," ","word","!","how"," ","you","."};
- //1.F1 f1("you");被解析为f1.operator(arg);
- F1 f1("you");
- remove_copy_if(vs.begin(),vs.end(),ostream_iterator<string>(cout,"\n"),f1);
- cout<<"****************************************"<<endl;
- //2.
- remove_copy_if(vs.begin(),vs.end(),ostream_iterator<string>(cout,"\n"),F1("you"));
- cout<<"****************************************"<<endl;
- //3.
- F1()("hello");//这是一个函数调用的行为
- return ;
- }
函数对象可以有自己的状态,也可以与函数配接器搭配使用。
- template<typename T, T add>
- struct m_plus
- {
- m_plus() { _add = add; }
- T operator()(const T& x) { return x + _add; }
- // 仿函数可以具有自己的状态
- int _add;
- };
为了能够拥有配接能力,每一个仿函数必须定义自己的响应型别。这些型别是为了让配接器能够取出,获得仿函数的某些信息。
unary_function
来反应一元仿函数的参数型别和返回值型别。
- //一元仿函数
- template <class Arg,class Result>
- struct unary_function{
- typedef Arg argument_type;
- typedef Result result_type;
- };
binary_function
来反应二元仿函数的第一参数型别第二参数型别返回值型别。
- //二元仿函数
- template <class Arg1,class Arg2,Class Result>
- struct binary_function{
- typedef Arg1 firs_argument_type;
- typedef Arg2 second_argument_type;
- typedef Result result_type;
- };
算数类仿函数
- 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 T>
- struct minus:public binary_function<T,T,T>{
- T operator()(const T & x,const T & y) const {return x - y;}
- };
- tmeplate<class T>
- struct muliplies:public binary_function<T,T,T>{
- T operator()(const T & x,const T & y) const {return x * y;}
- };
- tmeplate<class T>
- struct divides:public binary_function<T,T,T>{
- T operator()(const T & x,const T & y) const {return x / y;}
- };
- tmeplate<class T>
- struct modulus:public binary_function<T,T,T>{
- T operator()(const T & x,const T & y) const {return x % y;}
- };
- tmeplate<class T>
- struct negate:public unary_function<T,T>{
- T operator()(const T & x) const {return -x;}
- };
证同元素
意思是数值A若与该元素做op运算,会得到A自己。例如加法的证同元素是0,任何元素加上0都是自己本身。乘法的证同元素是1,任何元素乘1都为元素本身。
- template<class T>
- inline T identity_element(plus<T>)
- {return T();}
- template<class T>
- inline T identity_element(multiplies<T>)
- {return T();}
逻辑运算符仿函数
他们都继承与二元仿函数。
- template<class T>
- struct logical_and:public binary_function<T,T,bool>{
- bool operator()(const T & x,const T & y) const {return x&&y;}
- };
- template<class T>
- struct logical_or:public binary_function<T,T,bool>{
- bool operator()(const T & x,const T & y) const {return x||y;}
- };
- template<class T>
- struct logical_not:public unary_function<T,bool>{
- bool operator()(const T & x) const {return !x;}
- };
证同(identity)、选择(select)、投射(project)
- //证同函数。任何数值通过此函数后,不会有任何改变
- //此式运用于<stl_set.h>,用来指定RB-tree所需的KeyOfValue op
- //set元素键值即实值,所以采用identity
- template <class T>
- struct identity : public unary_function<T,T>{
- const T& operator()const T& x) const { return x; }
- };
- //选择函数:接收一个pair,返回其第一元素
- //此式运用于<stl_map.h>,用来指定RB-tree所需的KeyOfValue op
- //由于map系以pair元素的第一元素为其键值,所以采用select1st
- template <class Pair>
- struct select1st : public unary_function<Pair,typename Pair::first_type>
- {
- const typename Pair::first::first_type& operator()(const Pair& x)const{
- return x.first;
- }
- };
- //选择函数:接收一个Pair,传回其第二元素
- //SGI STL未运用此式
- template <class Pair>
- struct select2nd : public unary_function<Pair,typename Pair::second_type>
- {
- const typename Pair::first::second_type& operator()(const Pair& x)const{
- return x.second;
- }
- };
- //投射函数:传回第一参数,忽略第二参数
- //SGI STL未运用此式
- template<class Arg1,class Arg2>
- struct project1st : public binary_function<Arg1,Arg2,Arg1>{
- Arg1 operator()(const Arg1& x,const Arg2&)const{ return x; }
- };
- //投射函数:传回第二参数,忽略第一参数
- //SGI STL未运用此式
- template<class Arg1,class Arg2>
- struct project2nd : public binary_function<Arg1,Arg2,Arg2>{
- Arg1 operator()(const Arg1&,const Arg2& y)const{ return y; }
- };
函数对象(functional)的更多相关文章
- C++ Pirmer : 第十四章 : 重载运算符与类型转换之函数调用运算符与标准库的定义的函数对象
函数调用运算符 struct test { int operator()(int val) const { return (i > 0 ? i : -i); } }; 所谓的函数调用就是一个类重 ...
- C++11多态函数对象包装器
[C++11多态函数对象包装器] 针对函数对象的多态包装器(又称多态函数对象包装器)在语义和语法上和函数指针相似,但不像函数指针那么狭隘.只要能被调用,且其参数能与包装器兼容的都能以多态函数对象包装器 ...
- STL_iterator迭代器(3)——函数和函数对象
STL中,函数被称为算法,也就是说它们和标准C库函数相比,它们更为通用.STL算法通过重载operator()函数实现为模板类或模板函数.这些类用于创建函数对象,对容器中的数据进行各种各样的操作.下面 ...
- C++ Primer 学习笔记_62_重载操作符与转换 --调用操作符和函数对象
重载操作符与转换 --调用操作符和函数对象 引言: 能够为类类型的对象重载函数调用操作符:一般为表示操作的类重载调用操作符! struct absInt { int operator() (int v ...
- STL算法设计理念 - 预定义函数对象
预定义函数对象基本概念:标准模板库STL提前定义了很多预定义函数对象 1)使用预定义函数对象: #include <iostream> #include <cstdio> #i ...
- C++STL 预定义函数对象和函数适配器
预定义函数对象和函数适配器 预定义函数对象基本概念:标准模板库STL提前定义了很多预定义函数对象,#include <functional> 必须包含. 1使用预定义函数对象: void ...
- STL——仿函数(函数对象)
一.仿函数(也叫函数对象)概观 仿函数的作用主要在哪里?从第6章可以看出,STL所提供的各种算法,往往有两个版本,其中一个版本表现出最常用(或最直观)的某种运算,第二个版本则表现出最泛化的演算流程,允 ...
- 02--STL算法(函数对象和谓词)
一:函数对象(仿函数):实现状态记录等其他操作<相对于普通函数> 重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象. 即是重载了“ ...
- STL 算法中函数对象和谓词
STL 算法中函数对象和谓词 函数对象和谓词定义 函数对象: 重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象.一个类对象,表现出一个函数的特 ...
随机推荐
- Nginx+uWsgi生产部署Django
部署得过程很简单,部署得核心在于,为什么要这样做,每一个参数代表什么意思,最终的目的是得了解,一些基概念性的东西. uWsgi简介 说Uwsgi之前,先说一下Wsgi. 什么是Wsgi? WSGI: ...
- DZY Loves Colors CodeForces - 444C (线段树势能分析)
大意:有$n$个格子, 初始$i$位置的颜色为$i$, 美丽值为0, 有两种操作 将区间$[l,r]$内的元素全部改为$x$, 每个元素的美丽值增加$|x-y|$, $y$为未改动时的值 询问区间$[ ...
- HDOJ1003
#include<iostream> using namespace std; int main() { ],t=,m; cin >> n; while(n--) { cin ...
- ASP.NET的路由系统
一.URL与物理文件的分离 1.URL与物理文件的分离 对于一个 ASP.NET Web Form应用来说,任何一个请求都对应着某个具体的物理文件.部署在Web服务器上的物理文件可以是静态的(比如图片 ...
- 网络编程基础——System.Net.Socket 命名空间及相关类的使用
System.Net.Socket 命名空间主要提供制作 Socket 网络应用程序的相关类.(Socket 类.TcpClient 类.TcpListener 类 和 UdpClient 类) 1. ...
- SSH 绑定本地端口
SSH可以传送数据,那么我们可以让那些不加密的网络连接,全部改走SSH连接,从而提高安全性. 假定我们要让8080端口的数据,都通过SSH传向远程主机,命令就这样写: $ user@host SSH会 ...
- 一、WCF学习之旅-创建第一个服务
WCF基本介绍:http://baike.baidu.com/link?url=TGjLYt3HS4dt4-hIiGRknLy6udRsZ52QxJz9cmRKlR4NXbP9rCZDsKn2fDfG ...
- 《Python》 面向对象初识
一.面向对象初识: 1.结构上理解:类由两部分组成 class A: # class是类的关键字,类名首字母默认大写 name = 'alex' # 静态属性,静态变量,静态字段 def func ...
- 玩转X-CTR100 l STM32F4 l CAN通信
我造轮子,你造车,创客一起造起来!塔克创新资讯[塔克社区 www.xtark.cn ][塔克博客 www.cnblogs.com/xtark/ ] X-CTR100控制器STM32F4处理器内置CAN ...
- DevExpress v18.1新版亮点——WinForms篇(八)
用户界面套包DevExpress v18.1日前终于正式发布,本站将以连载的形式为大家介绍各版本新增内容.本文将介绍了DevExpress WinForms v18.1 的新功能,快来下载试用新版本! ...