函数对象:

重载函数调用操作符的类。其对象常称为函数对象(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. java web 学习笔记 - tomcat数据源

    1. 数据库源 以前的JDBC连接步骤为: 1.加载数据库驱动 2.通过DriverManger获取数据库连接connection 3.通过connection执行prepareStatement的响 ...

  2. 2017huas_ACM第三天

    暑假集训第三天. 就在刚才AC了第十题,本周做题拿到了满分. 软件工程专业没有学习C++语言,这在做题过程中给了我不少的麻烦.遇到什么不懂的,不确认的,都要上网查阅或者开了新项目自己尝试一下.耗费了不 ...

  3. webpack的详细介绍和使用

    // 一个常见的`webpack`配置文件 const webpack = require('webpack'); const HtmlWebpackPlugin = require('html-we ...

  4. CAD参数绘制半径标注(网页版)

    主要用到函数说明: _DMxDrawX::DrawDimRadial 绘制一个半径标注.详细说明如下: 参数 说明 DOUBLE dCenterX 被标注的曲线的中点X值 DOUBLE dCenter ...

  5. C 语言指针 5 分钟教程

    指针.引用和取值 什么是指针?什么是内存地址?什么叫做指针的取值?指针是一个存储计算机内存地址的变量.在这份教程里“引用”表示计算机内存地址.从指针指向的内存读取数据称作指针的取值.指针可以指向某些具 ...

  6. vue hash模式和404页面的配置

    1.设置我们的路由配置文件(/src/router/index.js): { path:'*', component:Error } 这里的path:’*’就是找不到页面时的配置,component是 ...

  7. 「 Luogu P1122 」 最大子树和

    # 题目大意 真讨厌题面写的老长老长的. 这个题的意思就是给定一棵无根树,每个节点都有一个美丽值(可能是负数),可以删掉一些边来删除某些点,现在要求你求出可以删掉任意条边的情况下,这个树上的剩余节点的 ...

  8. linux如何正确设置静态ip

    如果是新安装的CentOS7的用户,刚开始应该是没网的,ifconfig命令在CentOS7已经被淘汰了. 1.使用ip addr 即查看分配网卡情况. 2.激活网卡 [root@localhost ...

  9. buf.slice()

    buf.slice([start[, end]]) start {Number} 默认:0 end {Number} 默认:buffer.length 返回:{Buffer} 返回一个指向相同原始内存 ...

  10. 理解ZAB协议

    ZAB协议 介绍 1.zab协议是为分布式协调服务zookpeer专门设计的一种支持崩溃恢复的原子广播协议 2.在zookeeper中主要依赖ZAB协议来实现数据一致性,基于该协议zk实现了一种主备模 ...