C++【STL】

2023-10-31

一、基本概念

就是使一个类的使用看上去像一个函数。其实现就是类中实现一个operator(),这个类就有了类似函数的行为,就是一个仿函数类;

class Func {
public:
	void operator() () const {
		statements;
	}
};

1.1 为什么有仿函数,这样做有什么好处呢?

STL中也大量涉及到仿函数,有时仿函数的使用是为了函数拥有类的性质,以达到安全传递函数指针依据函数生成对象、甚至是让函数之间有继承关系、对函数进行运算操作的效果;

//less的定义
template<typename _Tp> 
struct less : public binary_function<_Tp, _Tp, bool>
{
      bool operator()(const _Tp& __x, const _Tp& __y) const
      	{ return __x < __y; }
};
 
//set的申明
template<typename _Key, 
				typename _Compare = std::less<_Key>,
				typename _Alloc = std::allocator<_Key>>
class set;
  • 比一般函数灵巧,可拥有状态;对于仿函数,可同时拥有两个状态不同的实体;
  • 每个仿函数都有其型别,可使用template来传参
  • 阔以使用内联函数,执行速度通常比函数指针更快
  • 阔以使用成员变量,以免去对一些公共变量的维护,也可以使重复使用的代码独立出来;
  • 也阔以进行依赖组合继承

1.2 仿函数可作为什么?

在开发过程经常需要使用已序的对象置于容器中,但我们一般不使用operator来排序,从而使用仿函数来操作;

class FuncSort {
public:
	/** 可自定义排序准则 */
	void operator() (const Person& p2) const {
		return num < p2.num;
	}
};

1.3 仿函数的内部状态?

/*----------------------------------------------------------------------
	> File Name: test.cpp
	> Author: Jxiepc
	> Mail: Jxiepc
	> Created Time: Mon 07 Mar 2022 04:08:01 PM CST
----------------------------------------------------------------------*/

#include <iostream>
#include <algorithm>
#include <list>

class Func {
    public:
        Func(int val) : m_val(val) {
        }

        int operator() () {
            return m_val++;
        }
    private:
        int m_val;
};

int main(int argc, char* argv[])
{
    std::list<int> coll;
    std::generate_n(std::back_inserter(coll),
            9,
            Func(4));

    for(auto& i:coll) {
        std::cout << i << " ";
    }
    std::cout <<  std::endl;
    return 0;
}

在这里插入图片描述

根据以上实例,仿函数可维持内部val的数值,进而叠加

1.3.1 pass by value

当使用传值时,算法不会改变随参数而来的仿函数状态,若改变只是其中的副本

int main(int argc, char* argv[])
{
    std::list<int> coll;
	Func f(1);
	std::generate_n(std::back_inserter(coll),
       		9,
       		f);
	std::generate_n(std::back_inserter(coll),
       		9,
       		f);
    for(auto& i:coll) {
        std::cout << i << " ";
    }
    std::cout << std::endl;
    return 0;
}

在这里插入图片描述

1.3.3 pass by reference

当使用引用传参(或使用for_each)时,即可从中获取结果反馈

int main(int argc, char* argv[])
{
    std::list<int> coll;
	Func f(1);
	std::generate_n<std::back_insert_iterator<std::list<int> >, int, Func&> (std::back_inserter(coll), 9, f);
	std::generate_n(std::back_inserter(coll),
       		9,
       		f);
    for(auto& i:coll) {
        std::cout << i << " ";
    }
    std::cout << std::endl;
    return 0;
}

在这里插入图片描述

1.3.4 for_each的回返值

出现了该函数可代替引用传参的方式,来获取存储的最终状态

// 返回值为仿函数类型,在仿函数内部提供一个状态返回即可通过该返回值进行查询;
template<typename InputIterator, typename Function>
Function for_each(InputIterator beg, InputIterator end, Function f) {
  while(beg != end) 
    f(*beg++);
}

三、判断式与仿函数

3.1 基本概念

即返回布尔值的一个函数或者仿函数;

3.2 判断式不应该被调用而改变自身的状态

为了保证这一点需要将operator声明为const成员函数

四、STL中标准仿函数

其中通过操作数进行划分为一元和二元,通过功能划分为算术、关系、逻辑运算;

4.1 满足STL的仿函数需要有哪些要求呢

必须定义相应的型别,为了让配置器能够萃取出类型;
该型别通过typedef设定,该操作于编译器即完成,不会影响效率及带来负担;
需要的型别有哪些呢?STL提供了unary_function和binary_function分别为一元二元的型别;

unarg_function

template<class Arg, class Result>
struct unary_function {
	typedef Arg argument_type;
	typedef Result result_type;
};

binary_function

template<class Arg1, class Arg2, class Result>
struct binary_function {
	typedef Arg1 first_argument_type;
	typedef Arg2 second_argument_type;
	typedef Result result_type;
};

这些型别在我们真正使用仿函数时一般用不到,那用在何处呢???

一般用在适配器上;
template<class Operation>
class binder1st {
protected:
	Operation op;
	typename Operation::first_argument_type value;
public:
	typename Operation::result_type operator()(const typename Opreator::second_argument_type& x) const {
		// ....
	}
};

在这里插入图片描述

4.2 STL中的identity、select、project仿函数

此类函数为STL了提供了间接性;
【identity】:证同函数,数值通过该函数,不会有任何变化;使用在map、set中告诉该类key如何得到;
【select】:选择函数,接收pair返回第一个或第二个参数;
【project】:投射函数,传回第一个或第二参数;

identity

template<class T>
struct identity : public unary_function<T, T> {
    const T& operator()(const T& x) const { return x; }
};

select

template<class Pair>
struct select1st : public unary_function<Pair, typename Pair::first_type>{
    const typename Pair::first_type& operator()(const Pair& x) const {
        return x.first;
    }
};

template<class Pair>
struct select2nd : public unary_function<Pair, typename Pair::second_type>{
    const typename Pair::second_type& operator()(const Pair& x) const {
        return x.seond;
    }
};

project

template<class Args1, class Args2>
struct project1st : public binary_function<Args1, Args2, Args1> {
    Args1 operator()(const Args1& x, const Args2&) const { return x;}
};

template<class Args1, class Args2>
struct project2nd : public binary_function<Args1, Args2, Args2> {
    Args2 operator()(const Args1&, const Args2& y) const { return y;}
};

4.3 常用仿函数

头文件为:functional

仿函数 作用
negate<>() - p
plus<>() p1 + p2
minus<>() p1 - p2
multiplies<>() p1 * p2
divides<>() p1 / p2
modulus<>() p1 % p2
equal_to<>() p1 == p2
no_equal_to<>() p1 != p2
less<>() p1 < p2
greater<>() p1 > p2
less_equal<>() p1 <= p2
greater_equal<>() p1>=p2
logical_not<>() !p
logical_and<>() p1 && p2
logical_or<>() p1 || p2
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++【STL】 的相关文章

  • 有没有办法为向量采用内存资源?

    我已经开始在我的项目中使用 pmr allocators 并且我已经看到使用它们带来了很多性能提升和优势 我使用的分配器与我在下面的简单示例中展示的非常相似 include
  • 请求的资源不支持 HTTP 方法“GET”

    我的路线配置正确 并且我的方法具有装饰标签 我仍然收到 请求的资源不支持 HTTP 方法 GET 消息 System Web Mvc AcceptVerbs GET POST System Web Mvc HttpGet public st
  • 在 C# 中实例化 python 类

    我已经用 python 编写了一个类 我想通过 IronPython 将其包装到 net 程序集中 并在 C 应用程序中实例化 我已将该类迁移到 IronPython 创建了一个库程序集并引用了它 现在 我如何真正获得该类的实例 该类看起来
  • 如何使用 saxon 将文档类型参数传递给 xslt?

    对于发送原子数据类型将使用类似 transformer SetParameter new QName customXml new XdmAtomicValue true 如何将 XML Node 作为参数从 C 传递给 XSLT 你能帮我么
  • Rx Framework:在超时时执行操作,而不中断原始可观察序列

    给定一个可观察的源 通过轮询低级设备的 变化 状态生成 observable source metacode IObservable
  • C++ 中的字符串到 LPCWSTR

    我正在尝试从字符串转换为 LPCWSTR 我使用多位 1 例如 LPCWSTR ToLPCWSTR string text LPCWSTR sw LPCWSTR text c str return sw 2 返回中文字符 LPCWSTR T
  • 限制纬度和经度值的模数

    我有代表纬度和经度的双精度数 我可以轻松地将经度限制为 180 0 180 0 具有以下功能 double limitLon double lon return fmod lon 180 0 360 0 180 0 这是有效的 因为一端是排
  • C# 动态 Linq 变量Where 子句

    我正在按照 Scott Gu 的文章创建动态 LINQhttp weblogs asp net scottgu archive 2008 01 07 dynamic linq part 1 using the linq dynamic qu
  • 将 Uploadify 与 Sharepoint 和 .net 结合使用

    我在共享点页面上有一些由 JQuery 生成的 html 我想在这个 html 中使用 uploadify 将文件上传到服务器 亚历山大 https stackoverflow com users 25427 alexander gyosh
  • 我需要一个树转储选项,该选项在当前的 gcc 版本中不再存在

    旧版本的 GCC 例如 4 0 2 或 4 1 2 有该选项 df see 用于调试程序或 GCC 的选项对于4 1 2 http gcc gnu org onlinedocs gcc 4 1 2 gcc Debugging Options
  • 如何从c++调用python

    我是Python新手 我尝试像这样从 C 调用 python 脚本 在 Raspberry Pi 中 std string pythonCommand python Callee py a b int res system pythonCo
  • 如何在单独的类库中管理客户端上下文对象?

    我正在尝试创建一个库 类库 对于共享点 它将拥有所有共享点 dll 来与共享点服务器交互上传文件 文档并创建文档库和文档集 现在这个库可以被使用客户端 例如 Web 应用程序 asp net webform 或 mvc 或控制台应用程序或
  • tcmalloc/jemalloc 和内存池之间有什么区别(以及选择的理由)?

    tcmalloc jemalloc是改进的内存分配器 还引入了内存池以更好地分配内存 那么它们之间有什么区别以及在我的应用中如何选择它们呢 这取决于您的程序的要求 如果您的程序有更多的动态内存分配 那么您 需要从可用的分配器中选择一个内存分
  • 如何检查是否发生溢出? [复制]

    这个问题在这里已经有答案了 可能的重复 检测 C C 中整数溢出的最佳方法 https stackoverflow com questions 199333 best way to detect integer overflow in c
  • 从 Linq 的列表中选择多个字段

    在 ASP NET C 中 我有一个结构 public struct Data public int item1 public int item2 public int category id public string category
  • 将 libpng 链接到 android 原生项目

    我在尝试在本机 Android 项目中加载 libpng 时遇到问题 编译器似乎无法识别 libpng 函数 但可以识别类型 如 png byte 它可以正常编译类型 但如果我添加函数 则会抛出错误 这是编译输出 Windows 7 cmd
  • XPath 选择具有特定属性值的元素?

    我在使用 XPath 选择节点时遇到问题 我将展示一个示例 由于实际数据量很大 xml 文件被缩短了 这是 XML 的子集
  • STL 向量、迭代器和插入 (C++)

    我有一个将向量的迭代器传递到的方法 在这个方法中 我想向向量中添加一些元素 但我不确定当只有迭代器时这是否可行 void GUIComponentText AddAttributes vector
  • Python 中的 C 指针算术

    我正在尝试将一个简单的 C 程序转换为 Python 但由于我对 C 和 Python 都一无所知 这对我来说很困难 我被 C 指针困住了 有一个函数采用 unsigned long int 指针并将其值添加到 while 循环中的某些变量
  • GetActiveObject() 与 GetObject() -- MK_E_UNAVAILABLE 错误

    All 我在将一些 VBA 代码转换为 C 时遇到一些问题 我们有一个充当本地 COM 服务器的第 3 方应用程序 在我们使用的VBA代码中获取对象 获取对现有对象的引用 e g Set appHandle GetObject ProgId

随机推荐

  • 《机器学习》第二章模型评估与选择 总结

    基本概念 误差 error 学习器的实际预测输出与样本的真实输出之间的差异 训练误差 training error 经验误差 empirical error 学习器在训练集上的误差 泛化误差 generalization error 学习器
  • Android四种Activity的加载模式

    建议首先阅读下面两篇文章 这样才可以更好的理解Activity的加载模式 Android的进程 线程模型 http www cnblogs com ghj1976 archive 2011 04 28 2031586 html 其中对 An
  • 设计模式之UML详解

    文章目录 1 什么是UML 2 UML图之类图 2 1 类 Class 2 2 接口 Interface 2 3 类图中关系 relation 1 泛化 继承 Generalization 2 实现 Realization 4 聚合 Agg
  • Windows 批处理(bat) for循环语句使用教程

    文章目录 for指令基本格式 指令参数 1 参数 d D 遍历文件夹 2 参数 l L 数字序列 3 参数 f F 打印文件内容 3 1 f delims 3 2 f tokens 2 delims 3 3 f skip 1 3 4 f e
  • mybatis 批量插入提升效率

    背景 最近工作中遇到了解析excel 然后批量插入 发现这个插入时间比较长 所以想要进行一些优化 大家可以跳过过程直接看结论 背景作 准备工作 创建一张测试表 CREATE TABLE user id int 11 NOT NULL AUT
  • 【猿人学WEB题目专解】猿人学第16题

    据说 看我文章时 关注 点赞 收藏 的 帅哥美女们 心情都会不自觉的好起来 前言 作者简介 大家好我是 user from future 意思是 来自未来的用户 寓意着未来的自己一定很棒 个人主页 点我直达 在这里肯定能找到你想要的 专栏介
  • 亚马逊 s3 boto3 中 Client,Resource和Session 区别。

    boto3 中 Client Resource和Session的不同 boto3 英文官方文档链接 https boto3 amazonaws com v1 documentation api latest guide resources
  • axios post请求get请求对传参的操作

    axios post请求get请求对传参的操作 特别说明 axios get传参 axios post传参 特别说明 以下都是基于 headers Content Type application x www form urlencoded
  • Python JS逆向篇(三)

    Python JS逆向篇 三 逆向z参数 js实现 py实现 实战 接口1 接口2 逆向主题 解析出网址里视频下的m3u8链接 注 文章所涉及内容只做学习参考交流 不做除此之外的任何其它用途 新手入门级 参考B站视频系列教程 https w
  • 有限状态机 python_python——有限状态机

    前言 使用Python 大部分时间花在了处理文本上 在处理文本的时候 如果对有限状态机有所了解的话 处理起来会更加得心应手 可以把文本看成一个流 然后有一个机器对这个流进行操作 这个机器有状态 不同的状态会做出不同的处理 状态会随着处理进行
  • 《代码大全2》阅读笔记09--Chapter 16 Controlling Loops

    Chapter 16 Controlling Loops 控制循环 循环 是一个非正式的术语 用来指代任意一种迭代控制结构 iterative control structure 任一能够导致应用程序反复执 行一段代码的结构 16 1 Se
  • Quartusii 调试工具之In-System Memory Content Editor

    本文主要介绍Quartusii 调试工具中的In System Memory Content Editor 其主要功能就是能实时更改RAM ROM中的数值 同时也可以修改FPGA内部定义的常数值 它是通过JTAG调试接口去完成RAM ROM
  • SQL去重distinct方法解析

    来源 https www cnblogs com lixuefang69 p 10420186 html SQL去重distinct方法解析 一 distinct 含义 distinct用来查询不重复记录的条数 即distinct来返回不重
  • 【HBZ分享】Clickhouse常用命令及SQL语法

    Clickhouse常用命令及SQL语法 建库语句 CREATE DATABASE 库名 例 CREATE DATABASE first clickhouse MergeTree建表语句 create table 库名 表名 字段1 字段2
  • 2023高教社数学建模国赛C题 - 蔬菜类商品的自动定价与补货决策(完整参考论文)

    摘要 商超 超市和零售店 在现代经济中扮演着至关重要的角色 然而 它们在蔬菜商品管理中面临着多重挑战 这些挑战包括如何准确预测销售趋势 合理制定价格策略 以及有效制定补货计划等问题 解决这些问题对于商超来说至关重要 因为它们直接影响着销售收
  • 图片自动标注工具调研

    AIDA https imageannotation nds ox ac uk 8443 AIDA 网页标注 支持圆圈和曲线标注 可导出json文件 Annotorious https annotorious github io demos
  • vivado2013.4和modelsim联合仿真

    vivado2013 4和modelsim联合仿真 Hello Panda 最近在做Zynq的项目 曾经尝试使用ISE PlanAhead XPS SDK组合和Vivado SDK来搭建工程 使用中发现前者及其不方便后者有诸多不稳定 近期得
  • 【202203】必应2022年3月壁纸链接合集

    全部壁纸 https wallpaper ddddavid cn subpages page 220329 html 2022 年 3 月份 https cn bing com th id OHR Shamrocks EN US911125
  • JMeter测试websocket

    在一个网站中 很多数据需要即时更新 比如期货交易类的用户资产 在以前 这种功能的实现一般使用http轮询 即客户端用定时任务每隔一段时间向服务器发送查询请求来获取最新值 这种方式的弊端显而易见 有可能造成数据更新不及时 如果前端轮询频率为5
  • C++【STL】

    文章目录 一 基本概念 1 1 为什么有仿函数 这样做有什么好处呢 1 2 仿函数可作为什么 1 3 仿函数的内部状态 1 3 1 pass by value 1 3 3 pass by reference 1 3 4 for each的回