侯捷 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.xdnf.cn/news/148951.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

DevEco Studio设置Nodejs提示路径只能包含英文、数字、下划线等

安装DevEco Studio 3.1.1 Release 设置Nodejs路径使用nodejs默认安装路径 &#xff08;C:\Program Files\nodejs&#xff09; 提示只能包含英文、数字、下划线等 , 不想在安装nodejs请往下看 nodejs默认路径报错 修改配置文件 1、退出DevEco Studio 2、打开配置文件 cmd控制台…

Visopsys 0.92 发布

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

卸载无用Mac电脑软件应用程序方法教程

如何在Mac电脑卸载应用程序&#xff1f;Mac OS系统的用户卸载软件时&#xff0c;大部分会选择直接将软件图标拖进废纸篓清倒。这种操作会留下大量程序残余文件占据磁盘空间&#xff0c;手动清理又怕误删文件&#xff0c;有时还会遇到无法移除的恶意/流氓软件。小编今天分享3种可…

zookeeper选举机制

全新集群选举 zookeeper 全新集群选举机制网上资料很多说法很模糊&#xff0c;仔细思考了一下&#xff0c;应该是这样 得到票数最多的机器>机器总数半数 具体启动过程中的哪个节点成为 leader 与 zoo.cfg 中配置的节点数有关&#xff0c;下面以3个举例 选举过程如下 server…

540. 有序数组中的单一元素

链接&#xff1a; 540. 有序数组中的单一元素 代码&#xff1a; 方法一&#xff1a;全数组的二分查找 思路和算法 假设只出现一次的元素位于下标 xxx&#xff0c;由于其余每个元素都出现两次&#xff0c;因此下标 xxx 的左边和右边都有偶数个元素&#xff0c;数组的长度是奇…

【2023年11月第四版教材】第18章《项目绩效域》(第一部分)

第18章《项目绩效域》&#xff08;第一部分&#xff09; 1 章节内容2 干系人绩效域2.1 绩效要点2.2 执行效果检查2.3 与其他绩效域的相互作用 3 团队绩效域3.1 绩效要点3.2 与其他绩效域的相互作用3.3 执行效果检查3.4 开发方法和生命周期绩效域 4 绩效要点4.1 与其他绩效域的相…

新版校园跑腿独立版小程序源码 多校版本,多模块,适合跑腿,外卖,表白,二手,快递等校园服务

最新校园跑腿小程序源码 多校版本&#xff0c;多模块&#xff0c;适合跑腿&#xff0c;外卖&#xff0c;表白&#xff0c;二手&#xff0c;快递等校园服务 此版本为独立版本&#xff0c;不需要** 直接放入就可以 需要自己准备好后台的服务器&#xff0c;已认证的小程序&#xf…

MyBatisPlus(九)模糊查询

说明 模糊查询&#xff0c;对应SQL语句中的 like 语句&#xff0c;模糊匹配“要查询的内容”。 like /*** 查询用户列表&#xff0c; 查询条件&#xff1a;姓名包含 "J"*/Testvoid like() {String name "J";LambdaQueryWrapper<User> wrapper ne…

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

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

Spring Cloud Loadbalancer 实现客户端负载均衡

针对 ribbon 负载均衡组件&#xff0c; 官方提出的替换解决方案是 Spring Cloud Loadbalancer。本次主要通过学习示例介绍了 Spring Cloud Loadbalancer 的基础使用。 1&#xff0c;引入pom <dependency><groupId>org.springframework.cloud</groupId><…

React18入门(第一篇)——JSX、TSX语法详解

文章目录 一、JSX 语法简介二、和 HTML 标签的几点不同三、JSX 属性四、JSX 事件4.1 简单点击事件4.2 类型限制4.3 带参数&#xff0c;箭头函数 五、插入 JS 变量六、JSX 中使用条件判断七、循环 一、JSX 语法简介 JSX - 是 JS 的扩展&#xff0c;写在 JS 代码里面&#xff0c…

ROS(0)命令及学习资源汇总

ROS安装命令 参考&#xff1a;Ubuntu20.04.4安装ROS Noetic详细教程 - 知乎 安装C和Python3 sudo apt-get install g sudo apt-get install python3 ROS运行小海龟仿真器 roscore确定ROS是否运行成功rosrun turtlesim turtlesim_node运行小海龟仿真器rosrun turtlesim turtle_…

【微信小程序开发】一文学会使用CSS控制样式布局与美化

引言 在微信小程序开发中&#xff0c;CSS样式布局和美化是非常重要的一部分&#xff0c;它能够为小程序增添美感&#xff0c;提升用户体验。本文将介绍如何学习使用CSS进行样式布局和美化&#xff0c;同时给出代码示例&#xff0c;帮助开发者更好地掌握这一技巧。 一、CSS样式布…

星宿UI2.4资源付费变现小程序源码 支持流量主

第一个小程序为星宿小程序 目前是最新版2.0 搭建星宿需要&#xff1a;备用域名 服务器 微信小程序账号 功能&#xff1a;文章展示 文章分类 资源链接下载 轮播图 直接下载附件功能 很多 很适合做资源类分享 源码下载&#xff1a;https://download.csdn.net/download/m0_6604…

mysql面试题17:MySQL引擎InnoDB与MyISAM的区别

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:MySQL引擎InnoDB与MyISAM的区别 InnoDB和MyISAM是MySQL中两种常见的存储引擎,它们在功能和性能方面有一些区别。下面将详细介绍它们之间的差异。…

【算法导论】线性时间排序(计数排序、基数排序、桶排序)

引言&#xff1a;   在排序的最终结果中&#xff0c;各元素的次序依赖于它们之间的比较&#xff0c;我们把这类排序算法称为比较排序&#xff0c;对于包含n个元素的输入序列来说&#xff0c;任何比较排序在最坏情况下都要经过 Ω ( n l g n ) \Omega(nlgn) Ω(nlgn)次比较&a…

学信息系统项目管理师第4版系列17_干系人管理

1. 项目经理和团队管理干系人的能力决定着项目的成败 2. 干系人满意度应作为项目目标加以识别和管理 3. 发展趋势和新兴实践 3.1. 识别所有干系人&#xff0c;而非在限定范围内 3.2. 确保所有团队成员都涉及引导干系人参与的活 3.3. 定期审查干系人群体&#xff0c;可与单…

星际争霸之小霸王之小蜜蜂(十六)--狂奔的花猫

系列文章目录 星际争霸之小霸王之小蜜蜂&#xff08;十五&#xff09;--剧将终场 星际争霸之小霸王之小蜜蜂&#xff08;十四&#xff09;--资本家的眼泪 星际争霸之小霸王之小蜜蜂&#xff08;十三&#xff09;--接着奏乐接着舞 星际争霸之小霸王之小蜜蜂&#xff08;十二…

Lucene学习总结之Lucene的索引文件格式

当我们真正进入到Lucene源代码之中的时候&#xff0c;我们会发现: Lucene的索引过程&#xff0c;就是按照全文检索的基本过程&#xff0c;将倒排表写成此文件格式的过程。Lucene的搜索过程&#xff0c;就是按照此文件格式将索引进去的信息读出来&#xff0c;然后计算每篇文档打…

Android开源 Skeleton 骨架屏 V1.3.0

目录 一、简介 二、效果图 三、引用 Skeleton 添加jitpack 仓库 添加依赖: 四、新增 “块”骨架屏 1、bind方法更改和变化&#xff1a; 2、load方法更改和变化&#xff1a; 五、关于上一个版本 一、简介 骨架屏的作用是在网络请求较慢时&#xff0c;提供基础占位&…