谓词是指普通函数或重载的 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 之 函数对象适配器的更多相关文章

  1. C++进阶 STL(3) 第三天 函数对象适配器、常用遍历算法、常用排序算法、常用算数生成算法、常用集合算法、 distance_逆序遍历_修改容器元素

    01昨天课程回顾 02函数对象适配器 函数适配器是用来让一个函数对象表现出另外一种类型的函数对象的特征.因为,许多情况下,我们所持有的函数对象或普通函数的参数个数或是返回值类型并不是我们想要的,这时候 ...

  2. ###STL学习--函数对象

    点击查看Evernote原文. #@author: gr #@date: 2014-08-13 #@email: forgerui@gmail.com 在stl中,函数对象被大量地使用,用以提高代码的 ...

  3. C++ STL 之 函数对象

    重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象,也叫仿函数(functor),其实就是重载“()”操作符,使得类对象可以像函数那样调用.注意 ...

  4. 条款20 STL函数对象

    继承标准STL的函数对象 1: struct PopLess : public atd::binary_function<state,state,bool> 2: { 3: bool op ...

  5. C++STL 预定义函数对象和函数适配器

    预定义函数对象和函数适配器 预定义函数对象基本概念:标准模板库STL提前定义了很多预定义函数对象,#include <functional> 必须包含. 1使用预定义函数对象: void ...

  6. STL 算法中函数对象和谓词

    STL 算法中函数对象和谓词 函数对象和谓词定义 函数对象: 重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象.一个类对象,表现出一个函数的特 ...

  7. 3.2 STL中的函数对象类模板

    *: STL中有一些函数对象类模板,如下所示: 1)例如要求两个double类型的x 和y 的积,可以: multiplies<double>()(x,y); 该表达式的值就是x*y的值. ...

  8. 【实习记】2014-08-15文档太少看着源码用cgicc+stl库之模板谓词函数对象

        总结1: 今天找到了昨天scanf的问题答案,scanf与printf一样的神奇而复杂,稍不留神,就会被坑.scanf函数在读入非空白符分割的多个字符串的解决方法是这个:/* 以 | 分割 * ...

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

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

随机推荐

  1. Linux 验证当前 Video0 不否是v4l设备 linux v4l 编程(1) Video 4 Linux 简介

    #include <stdio.h> #include <string.h> #include <errno.h> #include <sys/types.h ...

  2. Hibernate 自动更新表出错 More than one table found in namespace

    报错:Caused by: org.hibernate.tool.schema.extract.spi.SchemaExtractionException: More than one table f ...

  3. -bash: netstat: 未找到命令

    [root@localhost ~]# netstat -lunpt -bash: netstat: 未找到命令 [root@localhost ~]# yum -y install net-tool ...

  4. 阶段5 3.微服务项目【学成在线】_day17 用户认证 Zuul_18-身份校验-测试

    在顶级域名下配置 网关的地址在上面配置一下 重启nginx 拒绝访问后面的代码都加上 return null 开始测试 换成域名的方式访问 有cookie.但是拿不到header 加上header测试 ...

  5. Python3 中codecs进行文件的读取

    简单的概念与说明 编码(动词):按照某种规则(这个规则称为:编码(名词))将"文本"转换为"字节流".而在python 3中则表示:unicode变成str 解 ...

  6. using 关键字有两个主要用途

    转自:https://www.jianshu.com/p/5357dc4efcf8 using 关键字有两个主要用途: (一).作为指令,用于为命名空间创建别名或导入其他命名空间中定义的类型. (二) ...

  7. linux下的进程间通信概述

    管道(PIPE) FIFO(有名管道) XSI消息队列 XSI信号量 XSI共享内存 POSIX信号量 域套接字(Domain Socket) 信号(Signal) 互斥量(Mutex) 其中信号(s ...

  8. Object.defineProperty()方法学习笔记

    这是js中一个非常重要的方法,ES6中某些方法的实现依赖于它,VUE通过它实现双向绑定 此方法会直接在一个对象上定义一个新属性,或者修改一个已经存在的属性, 并返回这个对象 参数 Object.def ...

  9. charles 批量重复请求/重复发包工具

    本文参考:charles 批量请求 重复发包工具/repeat Charles 让你选择一个请求并重复,在测试后端接口的时候非常有用: Charles将请求重新发送到服务器,并将响应显示为新请求. 如 ...

  10. ipad 没有数据线如何上传文件到局域网windows PC 的解决方案

    是的,ios 的封闭性,真麻烦,不想用数据线,还不想用iTunes ,那你找对了. 方案一: (好像只能上传文件,不能下载,能在线查看媒体.) 我的想法是在Windows建立一个http file s ...