函数对象

简单地说,如果一个类重载了调用操作符(),那么这个类的对象就是所谓的函数对象。

 

一、 关于操作符重载的简单说明

1.     调用操作符()的重载必须以成员函数的形式出现,另外还必须以成员函数形式重载的操作符有:=、[ ]和->

2.     IO操作符<<和>>的重载则必须以友元函数的形式出现。

3.     下面4个符号是不能被重载的:

::、 .*、 . 和 ?:

 

二、 for_each函数的简单说明

0.      for_each在<algorithm>中定义

1.      函数原型:

template <class InputIterator, class Function>

Function for_each (InputIterator first, InputIterator last, Function f);

 

2.     参数:

first, last

Input iterators to the initial and final positions in a sequence. The range used is [first,last), which contains all the elements between first and last, including the element pointed by first but not the element pointed by last.

 

f

Unary function taking an element in the range as argument. This can either be a pointer to a function or an object whose class overloads operator().

Its return value, if any, is ignored.

 

3.     返回值:

和f的返回值一样

 



重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象。 [1]
一个类对象,表现出一个函数的特征,就是通过“对象名+( 参数列表)”的方式使用一个
类对象,如果没有上下文,完全可以把它看作一个函数对待。这是通过 重载类的
operator()来实现的。比如,对于调用
int s = sum(1, 1);
你可能把它看作一个 函数调用:
int sum(int i, int j) { return i+j; }
但很可能它是一个函数对象:
class Sum {
public:
int operator()(int i, int j) { return i+j; }
};
Sum sum;
而大多数情况是
template <class T>
class Sum {
public:
T operator()(T i, T j) { return i+j; }
};
Sum <int> sum;
“在标准库中,函数对象被广泛地使用以获得弹性”,标准库中的很多算法都可以
使用函数对象或者函数来作为自定的回调行为;



函数对象基本介绍
函数对象是一个普通的类对象,它的不普通之处在于它表现出一个函数的特征,即可以像普通函数那样进行函数调用操作。它的实现方式是对call操作符进行重载。
函数对象通常具有比普通函数更大的灵活性,例如,我们看下面这个例子。

[cpp]
bool GT6(int data) { 
    return data > 6; 

这个函数的实现目的是比较一个数是否大于6,加如我们现在需要这样的用户需求,就是测试一组10个用户输入的数字是否分别大于1~10,如果使用普通的函数,我们就不得不实现10个这样的函数版本(暂时不考率函数模板)。换个思路,如果我们使用函数对象,结果就大不一样了:
[cpp] 
class GT_int { 
    public: 
        GT_int(int pn):n(pn) { 
        } 
 
        bool operator()(int data) { 
            return data > n; 
        } 
    private: 
        int n; 

以上是一个函数对象的实现方式,它重载了call运算符,使它可以实现和函数同样的操作,使用构造函数来确定所比较的值。以下是它的使用方式:
[cpp] 
int data 
for (int i = 1; cin >> data && i <= 10; ++i) { 
    GT_int gt(i); 
    cout<< gt(data)<< endl; 

STL中的函数对象
函数对象在许多情况下非常有用,例如,它可以显示的指定STL算法库中的算法应该使用什么样的基本逻辑,例如,看下面的排序例子:

[cpp]
sort(svec.begin(), svec.end(), greater<string>()); 

一般说来,默认的sort函数使用’<’操作符对容器元素进行排序,而上面这个重载版本则使用了第三个参数greater<string>(),它是function头文件中定义的函数对象,可以比较第一个操作数是否大于第二个操作数,也就是说传递这个函数对象将使sort函数按降序方式进行排序。

在STL中,函数对象按照参数以及返回值的不同基本可以按照如下分类:
1. 产生器 没有参数
2. 一元函数 一个参数
3. 二元函数 两个参数
4. 一元谓词 一个参数,返回类型为bool型
5. 二元谓词 两个参数,返回类型为bool型

我们可以看一下函数accumulate的声明:
[cpp] 
template <class InputIterator, class T, class BinaryOperation> 
          T accumulate ( InputIterator first, InputIterator last, T init, 
                         BinaryOperation binary_op ); 
最后一个参数就要求是必须是一个二元函数。

函数适配器
前面已经介绍过容器适配器,迭代器适配器,今天我们来看一下函数适配器。和所有的适配器类似,函数适配器是用来让一个函数对象表现出另外一种类型的函数对象的特征。因为,许多情况下,我们所持有的函数对象或普通函数的参数个数或是返回值类型并不是我们想要的,这时候就需要函数适配器来为我们的函数进行适配。函数适配器最主要的可以分为两类:
1. 绑定适配器
该类适配器用于将二元函数适配成一元函数。


上图描述了绑定适配器的两种形式,binder1st将适配参数绑定到第一个参数上,binder2nd将适配参数绑定到第二个参数上。至于bind1st和bind2nd则实际上是为了避免冗长的声明而方便使用的适配模板函数而已。
我们还是先看一个例子:
[cpp] 
count_if(vec.begin(), vec.end(), bind2nd(less_equal<int>(), 10)); 

less_equal是STL为我们提供的一个函数对象,它有两个参数,器作用是比较第一个参数值是否<=第二个参数值。但是count_if要求我们第三个参数必须是一个一元谓词,所以我们用bind2nd对该函数对象进行适配,将10绑定到该函数对象的第二个参数上。现在cont_if执行的功能实际上就变成了查找给定序列中值<=10的元素的个数。

2. 反相器适配器
这一类适配器主要实现的功能是对函数的返回值进行适配,它对bool值进行取反,将true适配成false,false适配成ture。
例如我们如果想计算给定序列中元素值大于10的元素的个数,可以这样写:
[cpp] 
count_if(vec.begin(), vec.end(), not1(bind2nd(less_equal<int>(), 10))); www.2cto.com

STL为我们提供了两种反相器适配器,not1和not2,可进行适配的函数的参数分别是1个和两个。


作者:justaipanda
内容概要:该PPT详细介绍了企业架构设计的方法论,涵盖业务架构、数据架构、应用架构和技术架构四大核心模块。首先分析了企业架构现状,包括业务、数据、应用和技术四大架构的内容和关系,明确了企业架构设计的重要性。接着,阐述了新版企业架构总体框架(CSG-EAF 2.0)的形成过程,强调其融合了传统架构设计(TOGAF)和领域驱动设计(DDD)的优势,以适应数字化转型需求。业务架构部分通过梳理企业级和专业级价值流,细化业务能力、流程和对象,确保业务战略的有效落地。数据架构部分则遵循五大原则,确保数据的准确、一致和高效使用。应用架构方面,提出了分层解耦和服务化的设计原则,以提高灵活性和响应速度。最后,技术架构部分围绕技术框架、组件、平台和部署节点进行了详细设计,确保技术架构的稳定性和扩展性。 适合人群:适用于具有一定企业架构设计经验的IT架构师、项目经理和业务分析师,特别是那些希望深入了解如何将企业架构设计与数字化转型相结合的专业人士。 使用场景及目标:①帮助企业和组织梳理业务流程,优化业务能力,实现战略目标;②指导数据管理和应用开发,确保数据的一致性和应用的高效性;③为技术选型和系统部署提供科学依据,确保技术架构的稳定性和扩展性。 阅读建议:此资源内容详尽,涵盖企业架构设计的各个方面。建议读者在学习过程中,结合实际案例进行理解和实践,重点关注各架构模块之间的关联和协同,以便更好地应用于实际工作中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值