函数对象:

重载函数调用操作符的类。其对象常称为函数对象(function object),即它们是行为类似函数的对象。

一个类对象,表现出一个函数的特征,就是通过“对象名+(參数列表)”的方式使用一个类对象,假设没有上下文,全然能够把它看作一个函数对待。

这是通过重载类的operator()来实现的。

“在标准库中。函数对象被广泛地使用以获得弹性”。标准库中的非常多算法都能够使用函数对象或者函数来作为自定的回调行为;

demo

#include <iostream>
#include <cstdio> using namespace std; // 函数对象。类重载了()
template <typename T>
class ShowElement
{
public:
// 重载()
void operator()(T &t) {
cout << t << endl;
}
protected:
private:
int n;
}; // 函数模版
template <typename T>
void FuncShowElement(T &t)
{
cout << t << endl;
} // 普通函数
void FuncShowElement2(int &t)
{
cout << t << endl;
} void play01()
{
int a = 10;
ShowElement<int> showElement;
showElement(a); // 函数对象的调用,非常像一个函数,所以叫仿函数
// 10 FuncShowElement<int>(a);
FuncShowElement2(a); } int main()
{
play01(); return 0;
}

上面简单演示了函数对象的使用以及和普通函数定义的异同,看以下的demo。

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm> using namespace std; // 函数对象,类重载了()
template <typename T>
class ShowElement
{
public:
ShowElement()
{
n = 0;
}
// 重载()
void operator()(T &t) {
++n;
cout << t << ' ';
} void printN()
{
cout << "n: " << n << endl;
}
protected:
private:
int n;
}; // 函数模版
template <typename T>
void FuncShowElement(T &t)
{
cout << t << ' ';
} // 普通函数
void FuncShowElement2(int &t)
{
cout << t << ' ';
} void play01()
{
int a = 10;
ShowElement<int> showElement;
showElement(a); // 函数对象的调用,非常像一个函数,所以叫仿函数
// 10 FuncShowElement<int>(a);
FuncShowElement2(a); } // 函数对象的优点
// 函数对象属于类对象,能突破函数的概念。能保持调用状态信息
void play02()
{
vector<int> v;
v.push_back(1);
v.push_back(3);
v.push_back(5); for_each(v.begin(), v.end(), ShowElement<int>()); // 匿名函数对象,匿名仿函数
cout << endl;
// 1 3 5 for_each(v.begin(), v.end(), FuncShowElement2); // 通过回调函数
cout << endl;
// 1 3 5 // 改写一下类ShowElement
ShowElement<int> showElement;
/* for_each函数原型 template<class _InIt,
class _Fn1> inline
_Fn1 for_each(_InIt _First, _InIt _Last, _Fn1 _Func)
{ // perform function for each element
_DEBUG_RANGE(_First, _Last);
_DEBUG_POINTER(_Func);
_For_each(_Unchecked(_First), _Unchecked(_Last), _Func); return (_STD move(_Func));
}
*/
// 能够看出for_each算法的函数对象传递是元素值传递。不是引用传递
for_each(v.begin(), v.end(), showElement);
cout << endl;
showElement.printN(); // 所以这里打印结果并非我们预期的3
// n: 0 // 解决方式。for_each最后是把传进去的函数对象做了值返回
showElement = for_each(v.begin(), v.end(), showElement);
cout << endl;
showElement.printN(); // bingo
// n: 3
} int main()
{
//play01();
play02(); return 0;
}

结论:分清楚STL算法返回的值是迭代器还是谓词(函数对象)是非常重要的。

STL算法设计理念 - 函数对象和函数对象当參数和返回值的更多相关文章

  1. /编写一个函数,要求从给定的向量A中删除元素值在x到y之间的所有元素(向量要求各个元素之间不能有间断), 函数原型为int del(int A ,int n , int x , int y),其中n为输入向量的维数,返回值为删除元素后的维数

    /** * @author:(LiberHome) * @date:Created in 2019/2/28 19:39 * @description: * @version:$ */ /* 编写一个 ...

  2. STL算法设计理念 - 预定义函数对象

    预定义函数对象基本概念:标准模板库STL提前定义了很多预定义函数对象 1)使用预定义函数对象: #include <iostream> #include <cstdio> #i ...

  3. STL算法设计理念 - 函数对象和函数对象当参数和返回值

    函数对象: 重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象.一个类对象,表现出一个函数的特征,就是通过"对象名+(参数列表)&qu ...

  4. STL算法设计理念 - 函数适配器

    1)函数适配器的理论知识 2)常用函数函数适配器 标准库提供一组函数适配器,用来特殊化或者扩展一元和二元函数对象.常用适配器是: 1.绑定器(binder): binder通过把二元函数对象的一个实参 ...

  5. python--函数的返回值、函数参数的使用、名称空间与作用域、函数嵌套、函数对象

    今天学习内容有函数的返回值.函数参数的使用.名称空间与作用域.函数嵌套. 下来我们一一查看. 函数的返回值 看几个栗子: def func(x): y=func() print(y) def foo( ...

  6. STL算法设计理念 - 谓词,一元谓词demo

    谓词: 一元函数对象:函数参数1个: 二元函数对象:函数参数2个: 一元谓词 函数参数1个,函数返回值是bool类型,可以作为一个判断式 谓词可以使一个仿函数,也可以是一个回调函数. demo 一元谓 ...

  7. VC与JavaScript交互(三) --- CWebPage类调用javascript函数(给js函数传参,并取得返回值)

    ①需要一个别人写好的类CWebPage,将其对于的两个文件WebPage.h和WebPage.cpp添加到工程中. ②添加WebBrowser控件,在视图/对话框类的头文件中#include &quo ...

  8. VC/MFC中通过CWebPage类调用javascript函数(给js函数传参,并取得返回值)

    转自:http://www.cnblogs.com/javaexam2/archive/2012/07/14/2632959.html ①需要一个别人写好的类CWebPage,将其对于的两个文件Web ...

  9. JS基础研语法---函数基础总结---定义、作用、参数、返回值、arguments伪数组、作用域、预解析

    函数: 把一些重复的代码封装在一个地方,在需要的时候直接调用这个地方的代码就可以了 函数作用: 代码重用 函数的参数: 形参:函数定义的时候,函数名字后面的小括号里的变量 实参:函数调用的时候,函数名 ...

随机推荐

  1. linux设置ssh连接时间

    相信大家经常遇到SSH连接闲置一会就断开需要重新连接的痛苦,为了使SSH连接保持足够长的时间,我们可以使用如下两种设置 1.sshd服务配置: #vi /etc/ssh/sshd_config Cli ...

  2. github——团队合作

  3. Node.js——事件与发布机制

  4. c++通过管道pipe获取cmd输出的字符

    #include <stdio.h>#include<iostream>#include<string>using namespace std; // 描述:exe ...

  5. WEB下的excel批量导入功能

    新手学习中,记录一下excel导出功能实现的整个流程.使用框架ssm. control层 importExcel+parseDataItem: @RequestMapping("import ...

  6. swift class extension 与继承

    1.扩展中无法继承重写已有函数,不能添加函数. Extensions can add new functionality to a type, but they cannot override exi ...

  7. 解决docker pull镜像速度慢的问题

    直接下载Docker镜像时,由于种种原因,经常下载失败,即使连接成功也是很慢,怎么办呢 目前我知道可以提升速度的办法:DaoCloud 提供Docker Hub Mirror服务 用户可以进入Dock ...

  8. redis新特性

    摘自<redis 4.xcookbook> 从实例重启同步] 故障切换同步] 4.0之前从实例主键过期bug redis4新特性 Memory Command Lazy Free PSYN ...

  9. 【VScode】使用VScode 来写markdown时序图

    准备工作 在VScode中下载插件Markdown Preview Enhanced插件 创建一个.md文件 在VScode中打开文件,界面内点击右键可以看到Open preview to the s ...

  10. 看完这篇 你就能完全操作git 远程分支的增、删、改、查了

    最近项目中又用到了git所以在此总结一番,这篇主要针对的是怎么创建远程分支,如何删除远程分支. 首先,如何创建远程分支.将一系列前期准备工作准备完成后(创建\添加ssh): 在终端键入 git bra ...