谓词是指普通函数或重载的 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. 设计-Int(4)和Int(11)谁更美

    设计-Int(4)和Int(11)谁更美 [缘起] 大家平时在进行数据库设计的时候,如果遇到需要存储整数类型的数据的时候,通常会优先使用Int这个整数类型,在处理20亿级别的正负数值存储上,Int类型 ...

  2. HTML5 地理位置定位API(4)

    地理定位(geolocation)是最令人兴奋,而且得到了广泛支持的一个新API.通过这套API, JavaScript代码能够访问到用户的 当前位置信息.当然,访问之前必须得到用户的明确许可,即同意 ...

  3. WGS84 2 GCJ-02

    #include ; ) { x=-x; ff=; } cc=) ff=; ) ff=; } x=tt; ss=x; s2=x; tt=tt*tt; s2=s2*tt; ss=ss-s2* ) ss= ...

  4. ORA-00911: invalid character 错误解决集锦

    转: ORA-00911: invalid character 错误解决集锦 参考https://www.linuxidc.com/Linux/2017-05/144361.htm ORA-00911 ...

  5. 利用python批量修改word文件名的方法示例

    利用python批量修改word文件名的方法示例 最近不小心把硬盘给格式化了,由于当时的文件没有备份,所以一下所有的文件都没有了,于是只能采取补救措施,用文件恢复软件恢复了一部分的数据出来,但是恢复完 ...

  6. LINQ语法详解

    我会通过一些列的实例向大家讲解LINQ的语法. 先创建一个Person类,作为数据实体 public class Person { public string Name { get; set; } p ...

  7. Python3之高阶函数sorted

    排序算法 Python内置的sorted()函数可以对list进行排序 >>> sorted([36,5,-12,9,-21]) [-21, -12, 5, 9, 36] 此外,so ...

  8. Egret入门学习日记 --- 第十一篇(书中 4.1~4.6节 内容)

    第十一篇(书中 4.1~4.6节 内容) 好了,到了这篇开始,前三章都记录完了. 接下来就是到第四章了. 4.1节 的内容总结一下重点: 1.resource目录下default.res.json文件 ...

  9. selenium + python 环境配置 (三)之启动chrome

    安装启动chromedriver的方法和ie类似 2.启动chrome 即selenium调用ChromeDriver打开Chrome浏览器 ①下载并解压,你会得到一个chromedriver.exe ...

  10. 微信公众号对接JS-SDK接口 调用微信内置地图

    微信js-sdk开发文档:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html 1.页面配置 引用微信js- ...