STL函数适配器
一:适配器简介
C++中有三类适配器,分别是容器适配器,迭代器适配器和函数适配器,这里主要介绍函数适配器。
(一)函数适配器简介
STL中已经定义了大量的函数对象,但是有时候需要对函数返回值进行进一步的简单计算,或者填上多余的参数,
才可以带入其他的算法中进行下一步数据处理,不能直接带入算法。
函数适配器就实现了这一功能:将一种函数对象转化为另外一种符合要求的函数对象。
函数适配器可以分为4大类:
绑定适配器(bind adaptor),
组合适配器(composite adaptor),
指针函数适配器(pointer adaptor),
成员函数适配器(member function adaptor)
(二)绑定适配器(bind adaptor)

(三)组合适配器(composite adaptor)

(四) 指针函数适配器(pointer adaptor)

(五)成员函数适配器(member function adaptor)

二:函数适配器辅助函数
直接构造STL中的函数适配器通常会导致冗长的类型声明。---->之前说过模板函数和STL中类型是严格定义的,需要我们显式写出
为了简化函数适配器的构造,
STL还提供了函数适配器辅助函数,借助于泛型自动推断技术,无需显式的类型声明便可以实现函数适配器的构造。

三:常用函数适配器
标准库提供一组函数适配器,用来特殊化或者扩展一元和二元函数对象。
(一)绑定器(binder): 将二元函数对象转一元函数对象
binder通过把二元函数对象的一个实参绑定到一个特殊的值上,将其转换成一元函数对象。
C++标准库提供两种预定义的binder适配器(适配器辅助函数):
bind1st和bind2nd,前者把值绑定到二元函数对象的第一个实参上,后者绑定在第二个实参上。
(二)取反器(negator) : 操作谓词函数
negator是一个将函数对象的值翻转的函数适配器。
标准库提供两个预定义的ngeator适配器(适配器辅助函数):
not1翻转一元预定义函数对象的真值,而not2翻转二元谓词函数的真值。
(三)常用函数适配器案例:《重点》
1.使用绑定器和预定义函数对象
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional> //由于要使用到预定义函数对象,所以引入 using namespace std; template<typename T>
void ShowEle(const T& t) //用于打印容器数据
{
cout << t << " ";
}
int main()
{
vector<int> v1, v2, v3; for (int i = ; i < ;i++)
v1.push_back(rand() % ); //v1数据插入 //打印数据
for_each(v1.begin(), v1.end(), ShowEle<int>);
cout << endl; int num = count_if(v1.begin(), v1.end(), bind2nd(greater<int>(), 2));
cout << num << endl; system("pause");
return ;
}
补充:count和count_if
1)count(first,last,value):first是容器的首迭代器,last是容器的末迭代器,value是询问的元素,整个函数返回int型。count函数的功能是:统计容器中等于value元素的个数。 2)count_if(first,last,comp) (在comp为true的情况下计数) 或者 count_if(first,last,value,comp) (这个是在comp为true的情况下统计容器中等于value的元素):first为首迭代器,last为末迭代器,value为要查询的元素,comp为比较bool函数,为true则计数,函数返回型是int。 注:此两个函数复杂度是线性的,适用于小规模运算。count_if更加灵活
2.使用自定义谓词和绑定器《重点》
template<typename T>
void ShowEle(const T& t) //用于打印容器数据
{
cout << t << " ";
} template<typename T>
class Mygreater :public binary_function<T, T, bool> //1.自定义谓词需要继承binary_function
{
public:
bool operator() (const T& iLeft, const T& iRight) const //2.重载()函数需要加上const,变为常函数
{
return (iLeft > iRight);//如果是实现less<int>的话,这边是写return (iLeft<iRight);
}
}; int main()
{
vector<int> v1, v2, v3; for (int i = ; i < ;i++)
v1.push_back(rand() % ); //v1数据插入 //打印数据
for_each(v1.begin(), v1.end(), ShowEle<int>);
cout << endl; int num = count_if(v1.begin(), v1.end(), bind2nd(Mygreater<int>(), ));
cout << num << endl; system("pause");
return ;
}

template<class _Ty = void>
struct greater
: public binary_function<_Ty, _Ty, bool>
{ // functor for operator>
bool operator()(const _Ty& _Left, const _Ty& _Right) const
{ // apply operator> to operands
return (_Left > _Right);
}
};
参照预定义函数greater
3.使用自定义二元函数对象和绑定器《重点》
template<typename T>
void ShowEle(const T& t) //用于打印容器数据
{
cout << t << " ";
} //自定义二元函数对象---数据相加
template<typename T>
class MySumAdd :public binary_function<T, T, int>
{
public:
int operator()(const T& t1, const T& t2) const
{
return t1 + t2;
}
};
int main()
{
vector<int> v1, v2, v3; for (int i = ; i < ;i++)
v1.push_back(rand() % ); //v1数据插入 //打印数据
for_each(v1.begin(), v1.end(), ShowEle<int>);
cout << endl; v2.resize(10); //将v1中所有数据加2
transform(v1.begin(), v1.end(), v2.begin(), bind2nd(MySumAdd<int>(), 2));
//打印数据
for_each(v2.begin(), v2.end(), ShowEle<int>);
cout << endl; system("pause");
return ;
}

总之:自定义的仿函数和函数配接器搭配使用时,要继承自template <...> unary_function or template <...> binary_function
unary_function可以作为一个一元函数对象的基类,他定义了两个模板参数,分别是函数参数类型argument_type和返回值类型result_type,本身并不重载函数符(),由派生类去完成()操作符的重载工作。
binary_function可以作为一个二元函数对象的基类,他定义了三个模板参数,两个函数参数类型first_argument_type和second_argument_type,以及返回值类型result_type,本身并不重载函数符(),由派生类去完成()操作符的重载工作
STL函数适配器的更多相关文章
- STL 函数适配器(function adapter)
函数适配器(function adapter):通过不同函数适配器的绑定,组合和修饰能力,可以实现强大的功能,配合STL泛型算法完成复杂功能. 绑定(bind) template <class ...
- C++STL 预定义函数对象和函数适配器
预定义函数对象和函数适配器 预定义函数对象基本概念:标准模板库STL提前定义了很多预定义函数对象,#include <functional> 必须包含. 1使用预定义函数对象: void ...
- STL算法设计理念 - 函数适配器
1)函数适配器的理论知识 2)常用函数函数适配器 标准库提供一组函数适配器,用来特殊化或者扩展一元和二元函数对象.常用适配器是: 1.绑定器(binder): binder通过把二元函数对象的一个实参 ...
- function adapter(函数适配器)和迭代器适配器
所谓function adapter(函数适配器)是指能够将不同的函数对象(或是和某值或某寻常函数)结合起来的东西,它自身也是个函数对象. 迭代器适配器 运用STL中的迭代器适配器,可以使得算法能够 ...
- ###STL学习--适配器
点击查看Evernote原文. #@author: gr #@date: 2014-08-24 #@email: forgerui@gmail.com STL中的适配器. ###stl学习 |--迭代 ...
- 函数适配器bind2nd 、mem_fun_ref 源码分析、函数适配器应用举例
一.适配器 三种类型的适配器: 容器适配器:用来扩展7种基本容器,利用基本容器扩展形成了栈.队列和优先级队列 迭代器适配器:(反向迭代器.插入迭代器.IO流迭代器) 函数适配器:函数适配器能够将仿函数 ...
- 二分优化lis和STL函数
LIS:最长上升子序列: 这个题我们很显然会想到使用dp, 状态设计:dp[i]代表以a[i]结尾的LIS的长度 状态转移:dp[i]=max(dp[i], dp[j]+1) (0<=j< ...
- C++11之function模板和bind函数适配器
在C++98中,可以使用函数指针,调用函数,可以参考之前的一篇文章:类的成员函数指针和mem_fun适配器的用法. 简单的函数调用 对于函数: void foo(const string &a ...
- ----堆栈 STL 函数库 ----有待补充
#include<cstdio> #include<string> #include<vector> #include<iostream> using ...
随机推荐
- 大数据之路week07--day04 (Linux 中查看文件内容的关键字处)
Linux如何对文件内容中的关键字进行查找 如果是用vi打开文件后,在命令行下输入“/关键字” 如果是在没有打开文件的前提就用"cat 文件名 | grep "关键字" ...
- WebStorm 安装
官方下载地址:https://www.jetbrains.com/webstorm/ 下载 安装 等待.......... 安装完成........................ 开始使用(第一次 ...
- Linux监控系统概览
自从Linux系统诞生之始,监控系统就随之出现. 当然说到监控系统,我们就必须聊到SNMP协议,SNMP分为管理端(NMP)和被管理端. 管理端周期性的到被监控端采集数据,被监控端还需要有权限收集数据 ...
- 007——转载——C#将字符串转换为整型的三种方法的总结
(一)转载——C#将字符串转换为整型的三种方法的总结 在C#中,要将一个字符串或浮点数转换为整数,基本上有三种方法: (1)使用强制类型转换:(int)浮点数 (2)使用Convert.ToInt32 ...
- Neo4j 在Linux下的安装登录
第一步:安装JDK https://blog.csdn.net/qq_33951308/article/details/82933535 第二步:下载并安装neo4j 下载地址 或者直接用wget ...
- 爬虫(十一):scrapy中的选择器
Scrapy提取数据有自己的一套机制,被称作选择器(selectors),通过特定的Xpath或者CSS表达式来选择HTML文件的某个部分Xpath是专门在XML文件中选择节点的语言,也可以用在HTM ...
- Java 【 ArrayList应用 】 (SDUT 4069 C~K的班级)
Java 里面的所有的东西 数组.字符数组.等等,都要 new 新申请. C~K的班级 代码: package test; import java.util.*; public class Main ...
- 【SPOJ】Longest Common Substring II
[SPOJ]Longest Common Substring II 多个字符串求最长公共子串 还是将一个子串建SAM,其他字符串全部跑一边,记录每个点的最大贡献 由于是所有串,要对每个点每个字符串跑完 ...
- linux搭建代理服务器+蚁剑配置客户端代理
一:linux搭建代理服务器 0x00 介绍 关于搭建代理服务器的方法,我也是刚刚接触,从网上找了一些能够行得通的方法来给大家做个分享: 这里我用的是Tinyproxy作为代理服务软件.这个东西很小, ...
- 【2018.07.30】(广度优先搜索算法/队列)学习BFS算法小记
一些BFS参考的博客: https://blog.csdn.net/ldx19980108/article/details/78641127 https://blog.csdn.net/u011437 ...