函数对象与仿函数(function object and functor)
part 1. 仿函数在STL组件中的关系
如下图:
# 仿函数配合算法完成不同的策略变化。
# 适配器套接仿函数。
part 2. 仿函数介绍
传递给算法的“函数型实参”不一定得是函数,可以是行为类似函数的对象。这种对象称为函数对象(function object),或称为仿函数(functor)。——《STL标准库(第2版)》 P233
1. 函数对象 = 仿函数。并且,function object = functor
2. 函数对象(仿函数)有四种实现方式:函数指针(fucntion pointer)、lambda表达式、“带有成员函数 operator()”的class建立的object、“带有转换函数可以将自己转换为 pointer to function”的class所建立的object。
2.1 仿函数的实现原理:向算法传递的,终究是个函数。以上四种方式被调用时,终究是个函数。
3. 下面的所有例子,均为 vector 容器排序,但是采用不同的函数对象实现方式。
3.1 函数指针(function pointer)
使用函数指针作为“传递给算法的‘函数型实参’”。
bool compareLength(const string& lhs, const string& rhs)
{
return lhs.size() > rhs.size();
} int main()
{
vector<string> v = { "I", "love", "you" };
sort(v.begin(), v.end(), compareLength);
for(auto &s : v)
cout << s << " ";
return ;
}
// 输出结果:
// love you I
3.2 lambda表达式
lambda 是一种隐式的预定义函数对象。
使用 lambda表达式 作为“传递给算法的‘函数型实参’”。
int main()
{
vector<string> v = { "I", "love", "you" }; sort(v.begin(), v.end(),
[](const string& lhs, const string& rhs)
{ return lhs.size() > rhs.size(); }); for(auto &s : v)
cout << s << " ";
return ;
}
// 输出结果:
// love you I
3.3 “带有成员函数 operator()”的class/struct建立的object
根据个人经验,如果不考虑类内访问权限,在这里使用 struct 是写更少代码的写法。因为 class 默认的访问权限是 private ,所以还要多谢一行 public:。也就是说,用 class 你要这样写:
class CompareSize
{
public:
bool operator() (const string& lhs, const string& rhs)
{
return lhs.size() > rhs.size();
}
};
如果用 struct 你要这样写:
struct CompareSize
{
bool operator() (const string& lhs, const string& rhs)
{
return lhs.size() > rhs.size();
}
};
使用“带有成员函数 operator()”的class/struct建立的object 作为 “传递给算法的‘函数型实参’” 的完整代码如下:
struct CompareSize
{
bool operator() (const string& lhs, const string& rhs)
{
return lhs.size() > rhs.size();
}
}; int main()
{
vector<string> v = { "I", "love", "you" };
sort(v.begin(), v.end(), CompareSize());
for(auto &s : v)
cout << s << " ";
return ;
}
// 输出结果:
// love you I
3.3.1 用 struct 还是 class ?
使用 class 和 struct 定义类唯一的区别就是默认的访问权限——《C++ primer (5th)》 P241
所谓默认访问权限:定义在第一个访问说明符之前的成员,使用默认的访问权限。访问说明符有 public、protected、private。
3.3.2 用 lambda表达式 还是 functor?
首先,functor 泛指“带有成员函数 operator()”的 class/struct 建立的 object。其次,在语义明确,代码结构短小变量生存周期清晰,不追求复用的前提下,使用 lambda;否则使用 functor。
3.4“带有转换函数可以将自己转换为 pointer to function”的class所建立的object
(下次再写)
part 3. 仿函数适配器
(下次再写)
函数对象与仿函数(function object and functor)的更多相关文章
- C++11新特性之八——函数对象function
详细请看<C++ Primer plus>(第六版中文版) http://www.cnblogs.com/lvpengms/archive/2011/02/21/1960078.html ...
- 【C++】C++中的lambda表达式和函数对象
目录结构: contents structure [-] lambda表达式 lambda c++14新特性 lambda捕捉表达式 泛型lambda表达式 函数对象 函数适配器 绑定器(binder ...
- 02--STL算法(函数对象和谓词)
一:函数对象(仿函数):实现状态记录等其他操作<相对于普通函数> 重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象. 即是重载了“ ...
- C++ 谓词(predicate) 与 仿函数 ( functor (function object))
谓词与函数对象 谓词 predicate C++ 标准定义谓词如下: The Predicate parameter is used whenever an algorithm expects a f ...
- 函数对象(仿函数 functor)
简单地说,函数对象就是一个重载了()运算符的类实例,它可以像一个函数一样使用. #include <iostream> using namespace std; class Add { p ...
- 认识js函数对象(Function Object)
认识函数对象(Function Object) 可以用function关键字定义一个函数,对于每个函数可以为其指定一个函数名,通过函 数名来进行调用.这些都是代码给用户的印象,而在JavaScript ...
- STL——容器(Set & multiset)之 仿函数(函数对象)functor 的用法
Set/multiset 中元素的存储数据总是会按照从大到小或者从小到大排列,这个是怎么实现的?这就要说 "仿函数" 这个概念了. 仿函数概念 1. 尽管函数指针被广泛用于实现函数 ...
- C++ 11 - STL - 函数对象(Function Object) (上)
1. 定义 在STL中,可以把函数传递给算法,也可以把函数对象传递给算法. 那么,什么是函数对象呢? 我们来看下它的声明: class X { public: // define function c ...
- PythonStudy——函数对象 Function object
# 在python中,所有变量存放的值只要是地址,我们就称之为对象# -- 所有的变量都是用来存放地址的,所以都是对象# -- 存放整型的地址就是整型对象 | 存放函数的地址就是函数对象 | 存放文件 ...
随机推荐
- PAT甲1038 Recover the smallest number
1038 Recover the Smallest Number (30 分) Given a collection of number segments, you are supposed to r ...
- Spark+IDEA单机版环境搭建+IDEA快捷键
1. IDEA中配置Spark运行环境 请参考博文:http://www.cnblogs.com/jackchen-Net/p/6867838.html 3.1.Project Struct查看项目的 ...
- Oracle中的时间函数用法(to_date、to_char) (总结)
一.24小时的形式显示出来要用HH24 select to_char(sysdate,'yyyy-MM-dd HH24:mi:ss') from dual; select to_date('2005- ...
- spring boot+mybatis 系列
https://blog.csdn.net/linxingliang/article/details/52324937 https://www.cnblogs.com/a8457013/p/90749 ...
- 东哥讲义2 - 基于TCP,UDP协议的攻击,分析与防护
TCP SYN FLOOD 攻击 正常的TCP三次握手过程: 处于SYN FLOOD攻击状态时的三次握手过程: 查看示例:x_syn.c文件,一个实现了自定义mac,ip,tcp头部的syn floo ...
- Why is long2ip conversion important?
Frequently Asked Questions about Convert long to IP address https://long2ip.com/faq/ What is long2ip ...
- PHP之curl扩展
curl抓取远程文件 curl_init(); curl_setopt(); curl_exec(); curl_close(); 参数: //是curl收到HTTP response中的set-co ...
- 2018/04/04 PHP 中的 数组排序问题
简单说一下为什么要总结一下PHP中关于数组排序的问题. 在很多时候我们对于数组要进行排序,但是 PHP 中对于排序已经有了很多封装. 但是某些函数是修改原数组,一部分是返回修改后数组,与其一个个试,不 ...
- LoadRunner-参数化(添加参数值)
录制完脚本后,想要对脚本重复使用需要对某些值设定为参数,如accounts和password. 1.选中需要参数化的accounts值,点击右键->选择Replace with a parame ...
- 不再以讹传讹,GET和POST的真正区别(转)
add by zhj:按照restful的定义,GET是用于获取记录(幂等),POST用于创建记录(不幂等).GET也能带消息体?这个我没试过,文中说用浏览器发GET请求 是没法带的.另外,在< ...