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)的更多相关文章

  1. C++11新特性之八——函数对象function

    详细请看<C++ Primer plus>(第六版中文版) http://www.cnblogs.com/lvpengms/archive/2011/02/21/1960078.html ...

  2. 【C++】C++中的lambda表达式和函数对象

    目录结构: contents structure [-] lambda表达式 lambda c++14新特性 lambda捕捉表达式 泛型lambda表达式 函数对象 函数适配器 绑定器(binder ...

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

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

  4. C++ 谓词(predicate) 与 仿函数 ( functor (function object))

    谓词与函数对象 谓词 predicate C++ 标准定义谓词如下: The Predicate parameter is used whenever an algorithm expects a f ...

  5. 函数对象(仿函数 functor)

    简单地说,函数对象就是一个重载了()运算符的类实例,它可以像一个函数一样使用. #include <iostream> using namespace std; class Add { p ...

  6. 认识js函数对象(Function Object)

    认识函数对象(Function Object) 可以用function关键字定义一个函数,对于每个函数可以为其指定一个函数名,通过函 数名来进行调用.这些都是代码给用户的印象,而在JavaScript ...

  7. STL——容器(Set & multiset)之 仿函数(函数对象)functor 的用法

    Set/multiset 中元素的存储数据总是会按照从大到小或者从小到大排列,这个是怎么实现的?这就要说 "仿函数" 这个概念了. 仿函数概念 1. 尽管函数指针被广泛用于实现函数 ...

  8. C++ 11 - STL - 函数对象(Function Object) (上)

    1. 定义 在STL中,可以把函数传递给算法,也可以把函数对象传递给算法. 那么,什么是函数对象呢? 我们来看下它的声明: class X { public: // define function c ...

  9. PythonStudy——函数对象 Function object

    # 在python中,所有变量存放的值只要是地址,我们就称之为对象# -- 所有的变量都是用来存放地址的,所以都是对象# -- 存放整型的地址就是整型对象 | 存放函数的地址就是函数对象 | 存放文件 ...

随机推荐

  1. idea启动java Maven项目,出现" java: 程序包xxxx不存在"

    今天运行Maven项目的时候,出现了,Error:(19, 17) java: 程序包tracetool不存在的情况 本人的解决办法: (1)首先确保maven  pom文件不能报错,即文件上面不能有 ...

  2. Callable接口解析

    1.接口的定义: public interface Callable<V> { V call() throws Exception; } 2.Callable和Runnable的异同 先看 ...

  3. JAVA中只有值传递

    今天,我在一本面试书上看到了关于java的一个参数传递的问题: 写道 java中对象作为参数传递给一个方法,到底是值传递,还是引用传递? 我毫无疑问的回答:“引用传递!”,并且还觉得自己对java的这 ...

  4. 【Espruino】NO.07 获取电压值

    http://blog.csdn.net/qwert1213131/article/details/27985645 本文属于个人理解,能力有限,纰漏在所难免.还望指正! [小鱼有点电] 前几节的内容 ...

  5. 不需要更多JS框架了

    现在,JavaScript框架已成为Web项目开发不可或缺的一部分.那是因为很长一段时间以来,各种浏览器之间有很大的差别,人们不得不编写框架对此进行屏蔽.问题在于,各种浏览器甚至在基本问题上都难以取得 ...

  6. orm之路由层

    一.简单配置 1.参数 第一个参数是正则表达式(如果要精准匹配:‘^publish/$’),或者加斜杠('^publish/') 第二个参数是视图函数(不要加括号) urlpatterns = [ u ...

  7. matplotlib —— 调整坐标轴

    import matplotlib.pyplot as plt import numpy as np # 绘制普通图像 x = np.linspace(-1, 1, 50) y1 = 2 * x + ...

  8. Locust性能测试5-参数化批量注册

    前言 实现场景:所有并发虚拟用户共享同一份测试数据,并且保证虚拟用户使用的数据不重复. 例如,模拟10用户并发注册账号,总共有100个手机号,要求注册账号不重复,注册完毕后结束测试 准备数据 虚拟用户 ...

  9. 浅谈Android View滑动和弹性滑动

    引言 View的滑动这一块在实际开发中是非常重要的,无论是优秀的用户体验还是自定义控件都是需要对这一块了解的,我们今天来谈一下View的滑动. View的滑动 View滑动功能主要可以使用3种方式来实 ...

  10. jsp02

    el表达式,jstl标签 1.el表达式是什么? sun制定的一种规范,主要是给标签的属性赋值,或者直接输出. <%=user.name%> java5版本以上支持jsp的el表达式和js ...