STL算法设计理念 - 函数对象和函数对象当參数和返回值
函数对象:
重载函数调用操作符的类。其对象常称为函数对象(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算法设计理念 - 函数对象和函数对象当參数和返回值的更多相关文章
- /编写一个函数,要求从给定的向量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:$ */ /* 编写一个 ...
- STL算法设计理念 - 预定义函数对象
预定义函数对象基本概念:标准模板库STL提前定义了很多预定义函数对象 1)使用预定义函数对象: #include <iostream> #include <cstdio> #i ...
- STL算法设计理念 - 函数对象和函数对象当参数和返回值
函数对象: 重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象.一个类对象,表现出一个函数的特征,就是通过"对象名+(参数列表)&qu ...
- STL算法设计理念 - 函数适配器
1)函数适配器的理论知识 2)常用函数函数适配器 标准库提供一组函数适配器,用来特殊化或者扩展一元和二元函数对象.常用适配器是: 1.绑定器(binder): binder通过把二元函数对象的一个实参 ...
- python--函数的返回值、函数参数的使用、名称空间与作用域、函数嵌套、函数对象
今天学习内容有函数的返回值.函数参数的使用.名称空间与作用域.函数嵌套. 下来我们一一查看. 函数的返回值 看几个栗子: def func(x): y=func() print(y) def foo( ...
- STL算法设计理念 - 谓词,一元谓词demo
谓词: 一元函数对象:函数参数1个: 二元函数对象:函数参数2个: 一元谓词 函数参数1个,函数返回值是bool类型,可以作为一个判断式 谓词可以使一个仿函数,也可以是一个回调函数. demo 一元谓 ...
- VC与JavaScript交互(三) --- CWebPage类调用javascript函数(给js函数传参,并取得返回值)
①需要一个别人写好的类CWebPage,将其对于的两个文件WebPage.h和WebPage.cpp添加到工程中. ②添加WebBrowser控件,在视图/对话框类的头文件中#include &quo ...
- VC/MFC中通过CWebPage类调用javascript函数(给js函数传参,并取得返回值)
转自:http://www.cnblogs.com/javaexam2/archive/2012/07/14/2632959.html ①需要一个别人写好的类CWebPage,将其对于的两个文件Web ...
- JS基础研语法---函数基础总结---定义、作用、参数、返回值、arguments伪数组、作用域、预解析
函数: 把一些重复的代码封装在一个地方,在需要的时候直接调用这个地方的代码就可以了 函数作用: 代码重用 函数的参数: 形参:函数定义的时候,函数名字后面的小括号里的变量 实参:函数调用的时候,函数名 ...
随机推荐
- 使用Jenkins进行android项目的自动构建(4)
加入单元测试 android单元测试很多都是使用Instrumentation进行的,这里讲的是试用JUnit,为什么用JUnit呢?因为使用Instrumentation需要打包apk安装,然后再进 ...
- oracle 表之间的连接
排序 - - 合并连接(Sort Merge Join, SMJ): a) 对于非等值连接,这种连接方式的效率是比较高的. b) 如果在关联的列上都有索引,效果更好. c) 对于将2个较大的row s ...
- sh NonUniqueObjectException
话题引入: 使用hibernate进行更新操作时,首先调用了findById方法获取要修改的对象,此时session没有被关闭,接着重新创建一个对象,将要修改的属性值赋值给这个对象.调用修改方法抛出如 ...
- C 语言指针 5 分钟教程
指针.引用和取值 什么是指针?什么是内存地址?什么叫做指针的取值?指针是一个存储计算机内存地址的变量.在这份教程里“引用”表示计算机内存地址.从指针指向的内存读取数据称作指针的取值.指针可以指向某些具 ...
- DEBUG无法进入断点解决方法
18/08/17 任务栏:Tools->Options->Debugging->General->Require source files to exactly match t ...
- 为了安全请不要随意在页面中设置validateRequest="false"
为了安全请不要随意在页面中设置validateRequest="false" 分类: ASP.NET2009-04-12 17:24 531人阅读 评论(0) 收藏 举报 asp. ...
- eclipse包分层
方法很简单,如下图所示: 1.点击项目栏窗口的右上角的倒三角 2.选择Pachage Presentation(包呈现) 3.选择Hierarchical(分层)
- swiper 3D 覆盖流的使用方法
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name ...
- luogu 2-SAT 问题
题目大意:给出n个bool变量,以及m个条件,条件为x,vx,y,vy,表示 x == vx || y == vy . 求匹配. 题解: 最近新学了一下2-SAT算法.2-SAT指有若干个bool变量 ...
- [JOYOI] 1055 沙子合并
题目限制 时间限制 内存限制 评测方式 题目来源 1000ms 131072KiB 标准比较器 Local 题目描述 设有N堆沙子排成一排,其编号为1,2,3,-,N(N<=300).每堆沙子有 ...