侯捷 C++ STL标准库和泛型编程 —— 9 STL周围

最后一篇,完结辽!😋

9 STL周围

9.1 万用Hash Function

Hash Function的常规写法:其中 hash_val 就是万用Hash Function

class CustumerHash
{ 
public:size_t operator()(const Customer& c) const{ return hash_val(c.fname(), c.lname(), c.no()); }
};

还可以直接用函数实现,或者写一个 hash 的特化版本

原理:

通过三个函数重载实现从给入数据中逐一提取来不断改变 seed

// 第一个函数 首先进入该函数
template <typename... Types>
inline size_t hash_val(const Type&... args)
{size_t seed = 0; // 设置初始seedhash_val(seed, args...); // 进入第二个函数return seed; // seed就是最后的HashCode
}// 第二个函数 该函数中逐一提取一个参数
template <typename T, typename... Types>
inline void hash_val(size_t& seed, const T& val, const Types&... args)
{hash_combine(seed, val); // 逐一取val,改变seedhash_val(seed, args...); // 递归调用自己,直到取完进入第三个函数
}// 第三个函数
template <typename T>
inline void hash_val(size_t& seed, const T& val)
{hash_combine(seed, val); // 取最后一个val,改变seed
}// 改变seed的函数
template <typename T>
inline void hash_combine(size_t& seed, const T& val)
{// 乱七八糟的运算,越乱越好seed ^= hash<T>()(val) + 0x9e3779b9 + (seed<<6) + (seed>>2);
}

C++11中 variadic templates

从传入的内容(任意个数,任意元素类型)分为一个和其他,递归再分为一个和其他······

0x9e3779b9:是黄金比例!

9.2 Tuple

可以将一些东西组合在一起

9.2.1 用例
  • 创建 tuple

    tuple<string, int, int, complex<double>> t; tuple<int, float, string> t1(41, 6.3, "nico"); auto t2 = make_tuple(22, 44, "stacy");
    
  • 输出 tuple

    // 输出t1中的第一个
    cout << get<0>(t1) << endl; // 41
    cout << t << endl; // 在VS2022上并没有<<的重载
    
  • 运算

    t1 = t2;if(t1 < t2) // 以特定的方式进行的比较
    {...
    }
    
  • 绑定解包

    tuple<int, float, string> t3(77, 1.1, "more light");
    int i;
    float f;
    string s;tie(i, f, s) = t3; // i == 77, f == 1.1, s == "more light"
    
  • // tuple里有多少类型
    tuple_size< tuple<int, float, string> >::value; // 3// 取tuple里面的类型,前面一堆代表float
    tuple_element<1, TupleType>::type fl = 1.0; // float fl = 1.0;
    
9.2.2 原理

依然是使用 variadic templates,通过递归继承,不断从 ... 中提取内容

// 空的tuple
template <> class tuple<> {}; // 直到取完// tuple主体
template <typename Head, typename... Tail>
class tuple<Head, Tail...>: private tuple<Tail...> // 递归继承
{typedef tuple<Tail...> inherited;
public:tuple() {}tuple(Head v, Tail... vtail) : m_head(v), inherited(vtail...) {}...
protected:Head m_head; // 每次取出的元素
};

image-20230923111219018 👈🏻不断的继承就可以实现不同类型的组合了

其余函数:

...
{
public:...Head head() { return m_head; }inherited& tail() { return *this; } // 通过转型获得Tail部分...
};

image-20230923112317405 一般不这么用

9.3 type traits

9.3.1 用例

GCC2.9中:

默认的 __type_traits 进行了一系列泛化的设定(trivial 是不重要的意思)

 struct __true_type {};
struct __false_type {};template <class type>
struct __type_traits
{typedef __true_type this_dummy_member_must_be_first;typedef __false_type has_trivial_default_constructor;typedef __false_type has_trivial_copy_constructor;typedef __false_type has_trivial_assignment_operator;typedef __false_type has_trivial_destructor;typedef __false_type is_POD_type; // Plain Old Data 类似C的struct
};

还会通过特化来实现针对不同类型的设定,例

template <> struct __type_traits<int>
{typedef __true_type has_trivial_default_constructor;typedef __true_type has_trivial_copy_constructor;typedef __true_type has_trivial_assignment_operator;typedef __true_type has_trivial_destructor;typedef __true_type is_POD_type;
};

C++11中:
有了很多个 type traits,可以回答更多问题

测试:

cout << is_void<T>::value << endl;
cout << is_integral<T>::value << endl;
cout << is_floating_point<T>::value << endl;
cout << is_array<T>::value << endl;
...
image-20230923192837871

不论是什么类型都可以自动检测它的 traits,非常厉害!(里面有虚函数——就能自动检测出它有多态性)

9.3.2 原理

模板的作用

is_integral

依然是采用的一种问答的方式实现的

template <typename _Tp>
struct is_integral:public __is_intagral_helper<typename remove_cv<_Tp>::type>::type
{ };

首先 remove_cvconstvolatile

// 通过偏特化实现remove const
template <typename _Tp>
struct remove_const
{ typedef _Tp type };template <typename _Tp>
struct remove_const<_Tp const>
{ typedef _Tp type };// remove volatile 同理

再通过 __is_intagral_helper 进行问答

// 通过偏特化实现
template <typename>
struct __is_integral_helper:public false_type { };template <>
struct __is_integral_helper<bool>:public true_type { };template <>
struct __is_integral_helper<int>:public true_type { };template <>
struct __is_integral_helper<long>:public true_type { };...

其他深入 class 内部的一些 traits 比如是否有虚函数,是否是一个类,是否是POD等等,其实现可能都与编译器有关

9.4 move

moveable class 中有:

// move ctor
MyString(MyString&& str) noexcept // 用&&与普通版本区别开: _data(str._data), _len(str._len)
{str._len = 0;str._data = NULL; // 避免析构函数释放资源
}// move assignment
MyString& operator=(MyString&& str) noexcept
{if (this != &str){_len = str._len;_data = str._data;str._len = 0;str._data = NULL; // 避免析构函数释放资源}return *this;
}// dtor
virtual ~MyString()
{if(_data) delete _data; // 一定要检查
}
MyString C11(C1); // ctor
MyString C12(move(C1)); // move ctor

image-20230924094317369 是==浅拷贝==,并且把之前的指向去除了

对于 vector 这样的容器,其用 move 就只是 swap 了三根指针,非常快!

move 之后原来的东西不能再使用,比如拿数据插入容器,用临时对象,编译器看到就会自动使用 move 版本的

MyString C11(C1); 时,创建了一个实例 C11,编译器就不知道是否能用 move,就需要自己 MyString C12(move(C1)); 使用 move,但注意之后==一定不能用原来的 C1==

&&(右值引用)这是C++11引入的特性,右值引用用于处理临时对象或将资源所有权转移给其他对象,以提高性能和资源管理

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/94800.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

BASH shell脚本篇5——文件处理

这篇文章介绍下BASH shell中的文件处理。之前有介绍过shell的其它命令&#xff0c;请参考&#xff1a; BASH shell脚本篇1——基本命令 BASH shell脚本篇2——条件命令 BASH shell脚本篇3——字符串处理 BASH shell脚本篇4——函数 在Bash Shell脚本中&#xff0c;可以使用…

【C++】String -- 详解

⚪C语言中的字符串 C 语言中&#xff0c;字符串是以 \0 结尾的一些字符的集合&#xff0c;为了操作方便&#xff0c;C 标准库中提供了一些 str 系列的库函数&#xff0c;但是这些库函数与字符串是分离开的&#xff0c;不太符合 OOP 的思想&#xff0c;而且底层空间需要用户自己…

Is This The Intelligent Model(这是智能模型吗)

Is This The Intelligent Model 这是智能模型吗 Ruoqi Sun Academy of Military Science Defense Innovation Institute, Beijing, 100091, China E-mail: ruoqisun7163.com The exposed models are called artificial intelligent models[1-3]. These models rely on knowled…

讲讲项目里的仪表盘编辑器(二)

应用场景 正常来说&#xff0c;编辑器应用场景应该包括&#xff1a; 编辑器-预览 编辑器 最终运行时 怎么去设计 上一篇推文&#xff0c;我们已经大概了解了编辑器场景。接下来&#xff0c;我们来看预览时的设计 编辑器-预览 点击预览按钮&#xff0c;执行以…

[Unity][VR]Oculus透视开发图文教程1-Passthrough应用XR项目设置

Oculus现在已向开发者公布了如何使用自己的设备Camera,本系列课程就来手把手地告诉你如何在Unity中使用这个特性。 第一步,既然用的是Quest的特性,那就需要先引入Quest的Unity开发SDK。并且完成基本的VR开发项目设置。 新建Unity项目后,在编辑器界面先点击Window,打开资…

虹科分享 | 为工业机器人解绑,IO-Link wireless无线通讯技术可实现更加轻量灵活的机器人协作

背景 机器人是一种能够半自主或全自主工作的智能机器。中国电子学会组织发布的《中国机器人产业发展报告&#xff08;2022年&#xff09;显示&#xff0c;近些年&#xff0c;我国机器人市场规模持续快速增长&#xff0c;“机器人”应用不断拓展深入&#xff0c;预计五年年均增…

YOLOv5、YOLOv8改进:RepVGG结构

1.简介 论文参考&#xff1a;最新RepVGG结构: Paper 我们所说的“VGG式”指的是&#xff1a; 没有任何分支结构。即通常所说的plain或feed-forward架构。 仅使用3x3卷积。 仅使用ReLU作为激活函数。 主要创新点为结构重参数化。在训练时&#xff0c;网络的结构是多分支进…

Visopsys 0.92 发布

Visopsys 是一个 PC 机的操作系统&#xff0c;系统小型、快速而且开源。有着丰富的图形界面、抢先式多任务机制以及支持虚拟内存。Visopsys 视图兼容很多操作系统&#xff0c;但并不是他们的克隆版本。Visopsys 0.92 现已发布&#xff0c;此维护版本引入了多任务处理程序、文件…

二叉树题目:路径总和 II

文章目录 题目标题和出处难度题目描述要求示例数据范围 前言解法一思路和算法代码复杂度分析 解法二思路和算法代码复杂度分析 题目 标题和出处 标题&#xff1a;路径总和 II 出处&#xff1a;113. 路径总和 II 难度 4 级 题目描述 要求 给你二叉树的根结点 root \tex…

我的第一个react.js 的router工程

react.js 开发的时候&#xff0c;都是针对一个页面的&#xff0c;多个页面就要用Router了&#xff0c;本文介绍我在vscode 下的第一个router 工程。 我在学习react.js 前端开发&#xff0c;学到router 路由的时候有点犯难了。经过1-2天的努力&#xff0c;终于完成了第一个工程…

使用Pytorch构建神经网络

构建神经网络的典型流程 定义一个拥有可学习参数的神经网络遍历训练数据集处理输入数据使其流经神经网络计算损失值将网络参数的梯度进行反向传播以一定的规则更新网络的权重 我们首先定义一个Pytorch实现的神经网络: # 导入若干工具包 import torch import torch.nn as nn …

亲,您的假期余额已经严重不足了......

引言 大家好&#xff0c;我是亿元程序员&#xff0c;一位有着8年游戏行业经验的主程。 转眼八天长假已经接近尾声了&#xff0c;今天来总结一下大家的假期&#xff0c;聊一聊假期关于学习的看法&#xff0c;并预估一下大家节后大家上班时的样子。 1.放假前一天 即将迎来八天…

基于Web安全的Python编程(1)

目录 一、http协议基础知识介绍 1、http协议分类 2、请求方法 3、什么是URL 4、请求头 5、响应状态码 二、常用Python库、函数、操作 三、http常用请求方法 1、不带参请求 2、带参数请求&#xff08;get和post存在细微区别&#xff09; 四、http响应属性获取 1、获取…

计算机网络(六):应用层

参考引用 计算机网络微课堂-湖科大教书匠计算机网络&#xff08;第7版&#xff09;-谢希仁 1. 应用层概述 应用层是计算机网络体系结构的最顶层&#xff0c;是设计和建立计算机网络的最终目的&#xff0c;也是计算机网络中发展最快的部分 早期基于文本的应用 (电子邮件、远程登…

分布式架构篇

1、微服务 微服务架构风格&#xff0c;就像是把一个单独的应用程序开发为一套小服务&#xff0c;每个服务运行在自己的进程中&#xff0c;并使用轻量级机制通信&#xff0c;通常是 HTTP API。这些服务围绕业务能力来构建&#xff0c;并通过完全自动化部署机制来独立部署。这些…

Spring 原理

它是一个全面的、企业应用开发一站式的解决方案&#xff0c;贯穿表现层、业务层、持久层。但是 Spring仍然可以和其他的框架无缝整合。 1 Spring 特点 轻量级控制反转面向切面容器框架集合 2 Spring 核心组件 3 Spring 常用模块 4 Spring 主要包 5 Spring 常用注解 bean…

第十七章:Java连接数据库jdbc(java和myql数据库连接)

1.进入命令行&#xff1a;输入cmd&#xff0c;以管理员身份运行 windowsr 2.登录mysql 3.创建库和表 4.使用Java命令查询数据库操作 添加包 导入包的快捷键 选择第四个 找到包的位置 导入成功 创建java项目 二&#xff1a;连接数据库&#xff1a; 第一步&#xff1a;注册驱动…

设计模式 - 策略模式

目录 一. 前言 二. 实现 一. 前言 策略模式 (Strategy Pattern) 是指对一系列的算法定义&#xff0c;并将每一个算法封装起来&#xff0c;而且使它们还可以相互替换。此模式让算法的变化独立于使用算法的客户。 与状态模式的比较 状态模式的类图和策略模式类似&#xff0c;并…

VUE3照本宣科——内置指令与自定义指令及插槽

VUE3照本宣科——内置指令与自定义指令及插槽 前言一、内置指令1.v-text2.v-html3.v-show4.v-if5.v-else6.v-else-if7.v-for8.v-on9.v-bind10.v-model11.v-slot12.v-pre13.v-once14.v-memo15.v-cloak 二、自定义指令三、插槽1.v-slot2.useSlots3.defineSlots() 前言 &#x1f…

Windows下启动freeRDP并自适应远端桌面大小

几个二进制文件 xfreerdp # Linux下的&#xff0c;an X11 Remote Desktop Protocol (RDP) client which is part of the FreeRDP project wfreerdp.exe # Windows下的&#xff0c;freerdp2.0 主程序&#xff0c;freerdp3.0将废弃 sdl-freerdp.exe # Windows下的&…