如果f是一个function object,则可以将operator()作用于f身上。他是一个行为类似于函数的对象,为了能够行为类似函数,其类别中必须定义(或重载、重写)function call运算符(operator()),就可以在函数对象后加一对小括号以此来调用函数对象定义的operator()。

  调用函数对象时构造函数和operator()执行顺序

  1. 首先执行构造函数,构造出一个匿名对象
  2. 然后在执行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)的更多相关文章

  1. C++ Pirmer : 第十四章 : 重载运算符与类型转换之函数调用运算符与标准库的定义的函数对象

    函数调用运算符 struct test { int operator()(int val) const { return (i > 0 ? i : -i); } }; 所谓的函数调用就是一个类重 ...

  2. C++11多态函数对象包装器

    [C++11多态函数对象包装器] 针对函数对象的多态包装器(又称多态函数对象包装器)在语义和语法上和函数指针相似,但不像函数指针那么狭隘.只要能被调用,且其参数能与包装器兼容的都能以多态函数对象包装器 ...

  3. STL_iterator迭代器(3)——函数和函数对象

    STL中,函数被称为算法,也就是说它们和标准C库函数相比,它们更为通用.STL算法通过重载operator()函数实现为模板类或模板函数.这些类用于创建函数对象,对容器中的数据进行各种各样的操作.下面 ...

  4. C++ Primer 学习笔记_62_重载操作符与转换 --调用操作符和函数对象

    重载操作符与转换 --调用操作符和函数对象 引言: 能够为类类型的对象重载函数调用操作符:一般为表示操作的类重载调用操作符! struct absInt { int operator() (int v ...

  5. STL算法设计理念 - 预定义函数对象

    预定义函数对象基本概念:标准模板库STL提前定义了很多预定义函数对象 1)使用预定义函数对象: #include <iostream> #include <cstdio> #i ...

  6. C++STL 预定义函数对象和函数适配器

    预定义函数对象和函数适配器 预定义函数对象基本概念:标准模板库STL提前定义了很多预定义函数对象,#include <functional> 必须包含. 1使用预定义函数对象: void ...

  7. STL——仿函数(函数对象)

    一.仿函数(也叫函数对象)概观 仿函数的作用主要在哪里?从第6章可以看出,STL所提供的各种算法,往往有两个版本,其中一个版本表现出最常用(或最直观)的某种运算,第二个版本则表现出最泛化的演算流程,允 ...

  8. 02--STL算法(函数对象和谓词)

    一:函数对象(仿函数):实现状态记录等其他操作<相对于普通函数> 重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象. 即是重载了“ ...

  9. STL 算法中函数对象和谓词

    STL 算法中函数对象和谓词 函数对象和谓词定义 函数对象: 重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象.一个类对象,表现出一个函数的特 ...

随机推荐

  1. 上传xslx文件设置accept的MIME 类型

    .dotx:application/vnd.openxmlformats-officedocument.wordprocessingml.template.docx:application/vnd.o ...

  2. 从零开始学习Vue(一)

    因为最近有个项目的需求是,微信公众号+IOS/Android APP, 界面都很类似. 以往的做法是APP是调用JSON接口,后台只负责提供接口. 而H5,我以前都是用Jquery,用来写手机网站总是 ...

  3. SQL Server SqlCacheDependency 缓存依赖

     SQL server数据缓存依赖有两种实现模式,轮询模式,通知模式. 1  轮询模式实现步骤 此模式需要SQL SERVER 7.0/2000/2005版本以上版本都支持 主要包含以下几步:  1. ...

  4. bzoj2662

    题解: spfa最短路径 dp[i][j]表示到i,用了j掌权 然后转移 代码: #include<bits/stdc++.h> using namespace std; ; int n, ...

  5. DevExpress v18.1新版亮点——WPF篇(二)

    用户界面套包DevExpress v18.1日前终于正式发布,本站将以连载的形式为大家介绍各版本新增内容.本文将介绍了DevExpress WPF v18.1 的新功能,快来下载试用新版本!点击下载& ...

  6. ESET NOD32 Antivirus – 免费 3个月/ 3PC

    ESET NOD32 Antivirus 3个月/ 3PC俄罗斯活动,3用户3个月免费,仅用于EAV,不能用于ESS活动地址: 点此进入申请方法:一共2封邮件,第2封含3个月许可

  7. Cisco ASA(8.4)端口映射设定(ASDM)

    1.进入到Configuration→firewall→NAT Rules画面. 2.点“services”添加服务端口,此案例添加TCP 1443和UDP 1443端口映射 3.添加“Network ...

  8. mysql 下载和 安装

    一.下载mysql 1. 在浏览器里打开mysql的官网http://www.mysql.com/ 2. 进入页面顶部的"Downloads" 3. 打开页面底部的“Communi ...

  9. 算法训练 Multithreading

     算法训练 Multithreading   时间限制:1.0s   内存限制:256.0MB      问题描述 现有如下一个算法: repeat ni times yi := y y := yi+ ...

  10. B+与B-树

    1 .B-树定义 B-树是一种平衡的多路查找树,它在文件系统中很有用. 定义:一棵m 阶的B-树,或者为空树,或为满足下列特性的m 叉树:⑴树中每个结点至多有m 棵子树:⑵若根结点不是叶子结点,则至少 ...