仿函数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

MacOS M芯片部署ComfyUI:从环境排雷到插件生态一站式指南

本文为MacOS M系列芯片用户提供了一份详尽的ComfyUI部署指南。文章深入剖析了因架构差异导致的常见安装报错根源,并给出了基于MPS后端的正确PyTorch安装命令。从创建纯净Python虚拟环境、分步安装依赖,到验证GPU加速,手把手指导完成部署。同时,还推荐了包括管理器、汉化在内的必备插件,以完善使用生态,帮助用户一站式解决从环境搭建到效率提升的所有问题。

weixin_29261711的博客 993

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

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

空巢青年_rui的博客 3124

Ships Dataset:解锁海洋探索的数字宝库

在海上交通管理中,通过对船舶的持续跟踪,可以及时发现船舶的异常行为,如偏离航线、超速等,保障海上航行的安全。例如,通过分析船舶的航行数据和位置信息,合理安排船舶的停靠时间和装卸货物顺序,避免港口拥堵,提高船舶的周转率。同时,还精确标注了船舶在图像中的位置坐标,通过这些坐标,我们可以准确地定位船舶在图像中的具体位置,为后续的分析和处理提供了精确的依据。从繁忙运输货物的货船,到承载着能源使命的油轮,再到穿梭于海洋寻找鱼群的渔船 ,每一种船舶都有着独特的外形和功能,在数据集中留下了它们的身影。

qq_38220914的博客 1267

【论文翻译】Enhancing Channel Estimation in High Mobility OTFS Systems: A Novel Pilot-Based Method...

本文介绍了一种用于正交时频空间(OTFS)调制系统的新型基于导频的信道估计方法。我们提出的方法是在ZP-OTFS系统的零填充区域插入一行导频符号,具有减少开销和降低峰均功率比(PAPR)的显著优势。特别是,通过沿多普勒轴分布导频符号,我们的方法在高移动性场景下依然能够提供鲁棒且精确的信道估计,这是像TransPod这种时速超过1000 km/h的运输系统的一个典型特征。这一点至关重要,因为在此类场景下,多普勒频移可能会导致系统性能的严重退化。

Cuby的博客 1212

Function 与 Functor 区别

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

Super爬爬虫 1412

R语言 | 关联规则

关联规则(AssociationRules)是无监督的机器学习方法,用于知识发现,而非预测。 关联规则的学习器(learner)无需事先对训练数据进行打标签,因为无监督学习没有训练这个步骤。缺点是很难对关联规则学习器进行模型评估,一般都可以通过肉眼观测结果是否合理。 关联规则主要用来发现Pattern,最经典的应用是购物篮分析,当然其他类似于购物篮交易数据的案例也可以应用关联规则进行模式发现。

I think so I am 10万+

深入 Python 函数式编程模块 functools

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

二等碗 2316

DFT设计绪论

DFT设计的主要目的是为了将defect-free的芯片交给客户。 产品质量,通常使用Parts Per million(PPM)来衡量。 但是随着IC从SSI到VLSI的发展,在test上花销的时间越来越多,test的quality却很难提高,这使得DFT的engineer不断的发展着DFT的技术。 DFT engineer面对的第一个问题是设计内部的状态的可测试性问题。在...

ahr7882的博客 1195

openbmc 支持mctp over pcie(三)(支持作为endpoint)

本文介绍了在Intel BHS平台上支持MCTP over PCIe端点开发的调试方法。开发基于CodeConstruct和AspeedTech-BMC的开源项目,将内核驱动改为模块形式以便调试。内容包括DTS配置、驱动模块设置步骤,以及如何将BMC配置为端点设备。调试过程涉及内核模块加载、MCTPD启动、参数设置等关键命令,并展示了路由表、地址和邻居信息的测试结果。该方案仅为实验性工作,需注意停止其他使用/dev/aspeed-mctp0接口的应用。

wit_yuan的专栏 1554

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

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

qq_44272681的博客 269

SXU—软件测试方法和技术-朱少民-第四部分 软件测试流程和规范-附考点

软件测试方法和技术-朱少民-第四章 软件测试流程和规范—这本书最后一部分的考点整理,考点分析

weixin_63597914的博客 1752

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

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

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

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

weixin_34062469的博客 322

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

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

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

q610098308的专栏 1673

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

仿函数

仿函数,又叫做函数对象,是一个重载了"()"运算符的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、付费专栏及课程。

余额充值