C++ STL 之 函数对象适配器
谓词是指普通函数或重载的 operator()返回值是 bool 类型的函数对象(仿函数)。如果operator 接受一个参数,那么叫做一元谓词,如果接受两个参数,那么叫做二元谓词,谓词可作为一个判断式。
例如:
struct myfuncobj01
{
bool operator(int v){} // 接受一个参数,并且返回值为 Bool 即一元谓词
}
bool compare01(int v); // 同样是叫做一元谓词
struct myfuncobj02
{
bool operator(int v1,int v2){} // 接受两个参数,返回值为 Bool 即二元谓词
}
bool compare02(int v1,int v2); // 同样是叫做二元谓词
函数对象适配器是完成一些配接工作,这些配接包括绑定(bind),否定(negate),以及对一般函数或成员函数的修饰,使其成为函数对象。
如果希望函数对象适配器能对我们自己编写的函数对象有效,我们需要根据我们的函数对象类型继承 STL 的父类对象。
如果你本身是二元函数对象 需要继承
二元函数继承:public binary_function<参数类型,参数类型,返回类型>
一元函数继承:public unary_function<参数类型,返回类型>
#include <iostream>
#include <algorithm>
#include <functional>
#include <vector>
using namespace std; struct MyPrint : public binary_function<int, int, void>
{
void operator()(int v, int val) const
{
cout << "v = " << v << " val = " << val << endl;
cout << "v + val = " << v + val << endl;
} }; // 仿函数适配器 bind1st bind2nd 绑定适配器
void test01()
{
vector<int> v;
for (int i = ; i < ; i++)
{
v.push_back(i);
}
int addNum = ;
for_each(v.begin(), v.end(), bind2nd(MyPrint(), addNum));
// 绑定适配器 将一个二元函数对象转变成一元函数对象
// bind1st bind2nd区别?
// bind1st,将addNum绑定为函数对象的第一个参数
// bind2nd,将addNum绑定为函数对象的第二个参数
cout << "----------------------" << endl;
} struct MyPrint02
{
void operator()(int v)
{
cout << v << " ";
}
}; struct MyCompare : public binary_function<int, int, bool>
{
bool operator()(int v1, int v2) const
{
return v1 > v2;
}
}; struct MyGreater5 : public binary_function<int, int, bool>
{
bool operator()(int v, int val) const
{
cout << "v = " << v << " val = " << val << endl;
return v > val;
}
}; // 仿函数适配器 not1 not2 取反适配器
void test02()
{
vector<int> v;
for (int i = ; i < ; i++)
{
v.push_back(i);
}
for_each(v.begin(), v.end(), MyPrint02());
cout << endl;
// 正常排序 从大到小
sort(v.begin(), v.end(), MyCompare());
for_each(v.begin(), v.end(), MyPrint02());
cout << endl;
// 取反之后从小到大
sort(v.begin(), v.end(), not2(MyCompare()));
for_each(v.begin(), v.end(), MyPrint02());
cout << endl;
// not1 not2
// 如果对二元谓词取反,用not2
// 如果对一元谓词取反,用not1
vector<int>::iterator it = find_if(v.begin(), v.end(), not1(bind2nd(MyGreater5(), )));
if (it == v.end())
{
cout << "没有找到!" << endl;
}
else
{
cout << *it << endl;
}
cout << "----------------------" << endl;
} // 仿函数适配器 ptr_fun
void MyPrint03(int val, int val2)
{
cout << "val = " << val << " val2 = " << val2 << endl;
cout << "val + val2 = " << val + val2 << endl;
} void test03()
{
vector<int> v;
for (int i = ; i < ; i++)
{
v.push_back(i);
}
// ptr_func把普通函数转成函数对象
for_each(v.begin(), v.end(), bind2nd(ptr_fun(MyPrint03), ));
cout << "--------------" << endl;
} // 成员函数适配器 mem_fun mem_fun_ref
class Person
{
public:
Person(int age, int id) : age(age), id(id){}
void show()
{
cout << "age = " << age << " id = " << id << endl;
}
public:
int age;
int id;
}; void test04()
{
// 如果容器中存放的对象或者对象指针,我们for_each算法打印的时候,调用类自己提供的打印函数
vector<Person> v;
Person p1(, ), p2(, ), p3(, );
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
for_each(v.begin(), v.end(), mem_fun_ref(&Person::show));
cout << "--------------" << endl;
vector<Person*> v1;
v1.push_back(&p1);
v1.push_back(&p2);
v1.push_back(&p3);
for_each(v1.begin(), v1.end(), mem_fun(&Person::show));
// mem_fun_ref mem_fun区别?
// 如果存放的是对象指针 使用mem_fun
// 如果使用的是对象 使用mem_fun_ref
} int main()
{
test01();
test02();
test03();
test04();
getchar();
return ;
}
C++ STL 之 函数对象适配器的更多相关文章
- C++进阶 STL(3) 第三天 函数对象适配器、常用遍历算法、常用排序算法、常用算数生成算法、常用集合算法、 distance_逆序遍历_修改容器元素
01昨天课程回顾 02函数对象适配器 函数适配器是用来让一个函数对象表现出另外一种类型的函数对象的特征.因为,许多情况下,我们所持有的函数对象或普通函数的参数个数或是返回值类型并不是我们想要的,这时候 ...
- ###STL学习--函数对象
点击查看Evernote原文. #@author: gr #@date: 2014-08-13 #@email: forgerui@gmail.com 在stl中,函数对象被大量地使用,用以提高代码的 ...
- C++ STL 之 函数对象
重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象,也叫仿函数(functor),其实就是重载“()”操作符,使得类对象可以像函数那样调用.注意 ...
- 条款20 STL函数对象
继承标准STL的函数对象 1: struct PopLess : public atd::binary_function<state,state,bool> 2: { 3: bool op ...
- C++STL 预定义函数对象和函数适配器
预定义函数对象和函数适配器 预定义函数对象基本概念:标准模板库STL提前定义了很多预定义函数对象,#include <functional> 必须包含. 1使用预定义函数对象: void ...
- STL 算法中函数对象和谓词
STL 算法中函数对象和谓词 函数对象和谓词定义 函数对象: 重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象.一个类对象,表现出一个函数的特 ...
- 3.2 STL中的函数对象类模板
*: STL中有一些函数对象类模板,如下所示: 1)例如要求两个double类型的x 和y 的积,可以: multiplies<double>()(x,y); 该表达式的值就是x*y的值. ...
- 【实习记】2014-08-15文档太少看着源码用cgicc+stl库之模板谓词函数对象
总结1: 今天找到了昨天scanf的问题答案,scanf与printf一样的神奇而复杂,稍不留神,就会被坑.scanf函数在读入非空白符分割的多个字符串的解决方法是这个:/* 以 | 分割 * ...
- STL算法设计理念 - 预定义函数对象
预定义函数对象基本概念:标准模板库STL提前定义了很多预定义函数对象 1)使用预定义函数对象: #include <iostream> #include <cstdio> #i ...
随机推荐
- 严重性 代码 说明 项目 文件 行 禁止显示状态错误 C1128 节数超过对象文件格式限制: 请使用 /bigobj 进行编译。
严重性 代码 说明 项目 文件 行 禁止显示状态错误 C1128 节数超过对象文件格式限制: 请使用 /bigobj 进行编译. 默认情况下,对象文件最多可存放 65,536 (2^16) 个可寻址的 ...
- Mysql读写分离(Mycat版)
(1).读写分离概述 1)工作原理 读写分离是让主数据库处理事务性增删改操作(insert.delete.update),让从数据库处理查询查询操作(select). 2)作用 1.分担负载 2.主从 ...
- 简介Python设计模式中的代理模式与模板方法模式编程
简介Python设计模式中的代理模式与模板方法模式编程 这篇文章主要介绍了Python设计模式中的代理模式与模板方法模式编程,文中举了两个简单的代码片段来说明,需要的朋友可以参考下 代理模式 Prox ...
- Java点滴-List<Integer> list; 中尖括号的意思
这是jdk1.5后版本才有的新特性,泛型,指定传入的类型.这样定义之后,这个list只能接收Integer的对象. 以前没有加这个,传入的都是Object类型的,取出来的时候要强制类型转换为自己想要的 ...
- 【ARM-Linux开发】如何使用opkg在RicoBoard上在线安装软件包
类似于debian的apt-get,Redhat的yum类似,嵌入式Linux平台可以使用opkg实现在线安装软件包的功能,在我们提供的matrix文件系统中,已经包含了opkg工具,但是还没有配置一 ...
- java如何获取当前日期和时间
System.currentTimeMillis() 获取标准时间可以通过System.currentTimeMillis()方法获取,此方法不受时区影响,得到的结果是时间戳格式的.例如: 15431 ...
- VMware中 CentOs虚拟机的安装教程
首先点击创建新的虚拟机 选择典型安装,点击下一步 这里我们选择稍后安装操作系统,然后点击下一步 这里我们操作系统选择Linux操作系统,版本选择CentOs 7 64位,然后点击下一步 这里我们可以修 ...
- jqGrid常用方法
var jqGrid = $("#jqGrid"); // 获取选中行id[单行],test1就是最先一个行id var test1 = jqGrid.jqGrid("g ...
- [转帖]Oracle报错ORA-26563--当重命名表时碰到物化视图
Oracle报错ORA-26563--当重命名表时碰到物化视图 https://www.toutiao.com/i6739137279115133447/ 原创 波波说运维 2019-09-26 00 ...
- HikariCP连接池及其在springboot中的配置
主要配置如下: 配置项 描述 构造器默认值 默认配置validate之后的值 validate重置 autoCommit 自动提交从池中返回的连接 true true - connectionTime ...