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 ...
随机推荐
- Apache工作模式切换
一.apache运行模式切换 apache比较常用的工作模式有worker以及prefork两种方式 1.编译安装: 如果在编译时候不指定,系统默认的是prefork模式.如果需要换成worker模式 ...
- 基于JAVA JWT 实现OATUH TOKEN验证
什么是jwt? 最详细的是官网:https://jwt.io/ 这里以java的ssm框架为例,集成jwt. 1.pom.xml 导入jwt的包 <!-- jwt --> <!-- ...
- JEECG中修改时间相关自定义定时器
JEECG中使用,如下: @InitBinder public void initBinder(ServletRequestDataBinder binder) { binder.registerCu ...
- iOS-UIImageView和UIImage
UIImage self.imageView.contentMode = UIViewContentModeCenter;// 图片的内容模式 [self.imageView setFrame:CGR ...
- Memcached集群实现及原理介绍
一.Memcached集群介绍 1.自身通过算法保证数据唯一性2.集群形式对用户和Memcached都是透明的3.Memcached的集群是通过客户端实现的4.Memcached服务端相互不认识 二. ...
- python for循环 - python基础入门(11)
在python开发中,除了前篇文章介绍的while循环还有一个for循环也经常使用,两者使用都是大同小异,for循环的使用相对于while循环更加灵活,下面我们一起来了解下具体区别. 一.for 循环 ...
- ROS学习(一)Ros 中使用kinect
上的安装说明如下: 官网上明确写了如果安装windows kinect还需要安装一个驱动,但是有些ROS的书上并没有这么做,只提到了使用如下两步进行安装即可使用: sudo apt-get insta ...
- sqlite lib导入
依赖 1.System.Data.SQLite 2.SqlKata //https://www.nuget.org/profiles/SQLite //http://system.data.sqlit ...
- 利用Python进行数据分析_Numpy_基础_2
Numpy数据类型包括: int8.uint8.int16.uint16.int32.uint32.int64.uint64.float16.float32.float64.float128.co ...
- linux运维命令3
1.grep 逐行搜索所指定的文件或标准输入,并显示匹配模式的每一行. grep [-abcEFGhHilLnqrsvVwxy][-A<显示列数>][-B<显示列数>][-C& ...