当前位置: 首页 > news >正文

sgi_stl源码学习,官方文档3.2.3String package字符串封装,未完待续

https://www.boost.org/sgi/stl/character_traits.html

char_traits<char>
char_traits<wchar_t>

traits翻译为特征、特性类,一般是指某种类型的特性类应该提供的一组接口、类型定义。
web页面描述了一些接口要求。感觉没有什么特别的。直接看代码吧

char_traits.h文件中,以下两个头文件不在sgi stl范围内,属于c标准库的范围
在vs中创建一个空工程,#include “…/stl/char_traits.h” 后,就可以在vs中跳转过去,看到的是windows的实现。

#include <string.h>
#include <wchar.h>

以上两个头文件定义了strcpy_s、_memccpy之类的基础C函数,说明STL中的一些函数间接使用了C函数
__char_traits_base 定义了char类型的比较、赋值、拷贝、查找、求长度等基础函数

template <class _CharT, class _IntT> class __char_traits_base {
public:typedef _CharT char_type;typedef _IntT int_type;
#ifdef __STL_USE_NEW_IOSTREAMS //这个没用上,暂时可以不管typedef streamoff off_type;typedef streampos pos_type;typedef mbstate_t state_type;
#endif /* __STL_USE_NEW_IOSTREAMS */static void assign(char_type& __c1, const char_type& __c2) { __c1 = __c2; }static bool eq(const _CharT& __c1, const _CharT& __c2) { return __c1 == __c2; }static bool lt(const _CharT& __c1, const _CharT& __c2) { return __c1 < __c2; }static int compare(const _CharT* __s1, const _CharT* __s2, size_t __n) {for (size_t __i = 0; __i < __n; ++__i)if (!eq(__s1[__i], __s2[__i]))return __s1[__i] < __s2[__i] ? -1 : 1;return 0;}static size_t length(const _CharT* __s) {const _CharT __nullchar = _CharT();//默认构造函数必须置0(概念上可以不为0,定义无歧义空值即可)size_t __i;for (__i = 0; !eq(__s[__i], __nullchar); ++__i) {}return __i;}static const _CharT* find(const _CharT* __s, size_t __n, const _CharT& __c) {//此处传值或许更好,编译器优化后可能无差别for ( ; __n > 0 ; ++__s, --__n)if (eq(*__s, __c))return __s;return 0;}static _CharT* move(_CharT* __s1, const _CharT* __s2, size_t __n) {memmove(__s1, __s2, __n * sizeof(_CharT));//__n 是__s1 __s2的sizereturn __s1;}    static _CharT* copy(_CharT* __s1, const _CharT* __s2, size_t __n) {memcpy(__s1, __s2, __n * sizeof(_CharT));return __s1;} static _CharT* assign(_CharT* __s, size_t __n, _CharT __c) {for (size_t __i = 0; __i < __n; ++__i)__s[__i] = __c;return __s;}static int_type not_eof(const int_type& __c) {return !eq_int_type(__c, eof()) ? __c : 0;}static char_type to_char_type(const int_type& __c) {return static_cast<char_type>(__c);}static int_type to_int_type(const char_type& __c) {return static_cast<int_type>(__c);}static bool eq_int_type(const int_type& __c1, const int_type& __c2) {return __c1 == __c2;}static int_type eof() {return static_cast<int_type>(-1);//-1为无效值,大文件实际应该为long long -1}
};

POD表示"Plain Old Data"(简单老数据),衍生概念是指可简单拷贝内存复制对象的结构体,含有指针的就不适合简单拷贝。
char_traits不适用与非POD类型。

template <class _CharT> class char_traits //特化版本,与后面的char_traits<char>特化不一样,此处实际还没确定类型: public __char_traits_base<_CharT, _CharT>
{};
__STL_TEMPLATE_NULL class char_traits<char> //char的特化版本,重载了几个函数,典型的是调用C函数的几个: public __char_traits_base<char, int>{
public:static char_type to_char_type(const int_type& __c) {return static_cast<char_type>(static_cast<unsigned char>(__c));}static int_type to_int_type(const char_type& __c) {return static_cast<unsigned char>(__c);}static int compare(const char* __s1, const char* __s2, size_t __n) { return memcmp(__s1, __s2, __n); }  static size_t length(const char* __s) { return strlen(__s); }static void assign(char& __c1, const char& __c2) { __c1 = __c2; }static char* assign(char* __s, size_t __n, char __c){ memset(__s, __c, __n); return __s; }
};

wchar_t版本特化,wint_t实际是unsigned short

__STL_TEMPLATE_NULL class char_traits<wchar_t>: public __char_traits_base<wchar_t, wint_t>{};

basic_string在string中定义,web说明中没有很复杂,基本就是template <class _CharT, class _Traits, class _Alloc>三个的组合
实际代码如下

#pragma set woff 1174 //这种用法比较少见,据说是ms vs才支持的关闭告警语法
#pragma set woff 1375
// A helper class to use a char_traits as a function object.将char_traits用作函数对象
template <class _Traits>
struct _Not_within_traits //是否在内部找得到: public unary_function<typename _Traits::char_type, bool>{typedef const typename _Traits::char_type* _Pointer;const _Pointer _M_first;const _Pointer _M_last;_Not_within_traits(_Pointer __f, _Pointer __l) : _M_first(__f), _M_last(__l) {}bool operator()(const typename _Traits::char_type& __x) const {//找到了就在string内有__x,否则_Not_within_traitsreturn find_if(_M_first, _M_last, bind1st(_Eq_traits<_Traits>(), __x)) == _M_last;}//bind1st存储了op和1st参数,变成了一个一元仿函数对象,再去操作序列中的元素。
};
template <class _InputIter, class _Predicate>
inline _InputIter find_if(_InputIter __first, _InputIter __last,_Predicate __pred,input_iterator_tag){while (__first != __last && !__pred(*__first))//遇到相等就停,不等于就循环下去++__first;return __first;
}
template <class _Traits>
struct _Eq_traits: public binary_function<typename _Traits::char_type,typename _Traits::char_type,bool>{bool operator()(const typename _Traits::char_type& __x,const typename _Traits::char_type& __y) const{ return _Traits::eq(__x, __y); }//实际就是判断是否相等。封装是为了编译期检查?
};
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 _Tp>//_Operation == _Eq_traits<_Traits>()
inline binder1st<_Operation> //返回值是一个函数对象,编译后可能是函数指针,或者内联
bind1st(const _Operation& __fn, const _Tp& __x) {typedef typename _Operation::first_argument_type _Arg1_type;return binder1st<_Operation>(__fn, _Arg1_type(__x));//说明__x是__fn的第一个参数
}
template <class _Operation> 
class binder1st  : public unary_function<typename _Operation::second_argument_type,typename _Operation::result_type> {
protected:_Operation op;//操作的存储,使得当前类替代了被绑定的操作(操作的递归替换)typename _Operation::first_argument_type value;//降元的本质就是将部分存到仿函数内部。
public:binder1st(const _Operation& __x,const typename _Operation::first_argument_type& __y): op(__x), value(__y) {}//bind1st(_Eq_traits<_Traits>(), __x)把第一个参数绑定,实际是存储起来typename _Operation::result_typeoperator()(const typename _Operation::second_argument_type& __x) const {//与第二个参数进行操作(eg:判断是否相等)return op(value, __x); }
};

前面这段代码比较难看懂的是以下这句
return find_if(_M_first, _M_last, bind1st(_Eq_traits<_Traits>(), __x)) == _M_last;
//bind1st存储了op和1st参数,变成了一个一元仿函数对象,再去操作序列中的元素。
//find_if返回值是序列的指针,指针指向的对象满足bind1st绑定后的一元仿函数(返回值true)
find_if这种函数只接受一元仿函数,bind1st实现了操作降元(二元操作降到一元操作),类似降元都可以模仿着写,本质就是将第一个元存到仿函数内部。

// General base class.
template <class _Tp, class _Alloc, bool _S_instanceless>//instanceless _Alloc是否无实例
class _String_alloc_base { //提供内存管理
public:typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type;//new delete仿函数类型定义allocator_type get_allocator() const { return _M_data_allocator; }//获得内部的new delete仿函数对象_String_alloc_base(const allocator_type& __a): _M_data_allocator(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0)   {}
protected:_Tp* _M_allocate(size_t __n){ return _M_data_allocator.allocate(__n); }//newvoid _M_deallocate(_Tp* __p, size_t __n) {if (__p)_M_data_allocator.deallocate(__p, __n); //delete}
protected:allocator_type _M_data_allocator; //仿函数对象(默认false,无实例的false,就是此处有_Alloc示例)此处占内存_Tp* _M_start;//起始指针_Tp* _M_finish;//已用范围的尾部指针_Tp* _M_end_of_storage; //标识最大容量指针
};

_String_alloc_base 的特化版本

// Specialization for instanceless allocators.
template <class _Tp, class _Alloc>
class _String_alloc_base<_Tp,_Alloc,true> {
public:typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type;//此处无实例化,就是定义allocator_typeallocator_type get_allocator() const { return allocator_type(); }_String_alloc_base(const allocator_type&) : _M_start(0), _M_finish(0), _M_end_of_storage(0) {}
protected:typedef typename _Alloc_traits<_Tp, _Alloc>::_Alloc_type _Alloc_type;_Tp* _M_allocate(size_t __n)    { return _Alloc_type::allocate(__n); }void _M_deallocate(_Tp* __p, size_t __n)    { _Alloc_type::deallocate(__p, __n); }
protected:_Tp* _M_start;_Tp* _M_finish;_Tp* _M_end_of_storage;
};
template <class _Tp, class _Alloc>
class _String_base : public _String_alloc_base<_Tp, _Alloc,_Alloc_traits<_Tp, _Alloc>::_S_instanceless>{
protected:typedef _String_alloc_base<_Tp, _Alloc,_Alloc_traits<_Tp, _Alloc>::_S_instanceless> _Base;typedef typename _Base::allocator_type allocator_type;void _M_allocate_block(size_t __n) { if (__n <= max_size()) {_M_start  = _M_allocate(__n);_M_finish = _M_start;_M_end_of_storage = _M_start + __n;}else_M_throw_length_error();}void _M_deallocate_block() { _M_deallocate(_M_start, _M_end_of_storage - _M_start); }  size_t max_size() const { return (size_t(-1) / sizeof(_Tp)) - 1; }_String_base(const allocator_type& __a) : _Base(__a) { }  _String_base(const allocator_type& __a, size_t __n) : _Base(__a){ _M_allocate_block(__n); }~_String_base() { _M_deallocate_block(); }void _M_throw_length_error() const;//两种异常之一。类外定义,防止内联?void _M_throw_out_of_range() const;//两种异常之一
};
// Helper functions for exception handling.
template <class _Tp, class _Alloc> 
void _String_base<_Tp,_Alloc>::_M_throw_length_error() const {__STL_THROW(length_error("basic_string"));//两种异常之一
}
template <class _Tp, class _Alloc> 
void _String_base<_Tp, _Alloc>::_M_throw_out_of_range() const {__STL_THROW(out_of_range("basic_string"));//两种异常之一
}

未完待续

相关文章:

sgi_stl源码学习,官方文档3.2.3String package字符串封装,未完待续

https://www.boost.org/sgi/stl/character_traits.html char_traits<char> char_traits<wchar_t>traits翻译为特征、特性类&#xff0c;一般是指某种类型的特性类应该提供的一组接口、类型定义。 web页面描述了一些接口要求。感觉没有什么特别的。直接看代码吧 c…...

从JavaScript到Java(一):基础知识

Hello World Java和JavaScript虽然有不同的特点&#xff0c;但在一些概念和知识点上是相似的。本文从JavaScript开发者的角度出发&#xff0c;帮助你理解Java基础知识&#xff08;反过来也行&#xff09;。 // 解释型 console.log("Hello, World!");// 编译型 pub…...

Android编舞者类Choreographer小结

Android编舞者类Choreographer小结 作用 编舞者类的作用主要是控制绘制节奏&#xff0c;用于发起一次vsync垂直同步信号的监听&#xff0c;当垂直同步信号来的时候会回调注册的Runnable或者FramCallback Choreographer对象获取 Choreographer对象是通过它的getInstance方法…...

大专升本科难度大吗 需要考哪些科目

大专学历可以通过自考和成考提升学历到本科&#xff0c;自考的考试科目有12-16门左右&#xff0c;考试内容不难&#xff0c;但是考试周期长&#xff0c;需要考生通过所有课程才能申请毕业。成考专升本考试科目有政治&#xff0c;外语和专业课&#xff0c;考试内容简单&#xff…...

考研复试-英语问答+解答

每个问题2~3min 一、 1.考官问问题&#xff0c;没听明白 I’m sorry, I didn’t hear that clearly. May I ask you to repeat it, please? Sorry, I have no clear idea about this question for now, but I will think about it later. And if possible, I want to discuss …...

python 文件相关的操作 常用函数(读文件、写文件、文件的追加内容、修改文件内容、复制文件、按行读取文件、with open) json文件的读取

常用函数&#xff1a;open&#xff08;打开文件&#xff09;&#xff0c;read&#xff08;读文件到程序中&#xff09;&#xff0c;write&#xff08;写程序中的变量到文件&#xff09;&#xff0c;close&#xff08;关闭文件&#xff09; 示例1&#xff1a;读文件&#xff08…...

python 系列 06 -生成及解析二维码

0 说明 二维码不止一种&#xff0c;本文介绍最常见的QR二维码。由于不能发二维码截图&#xff0c;所以所有的执行结果都隐去了。完整版本可以移步到此查看&#xff1a;https://vblogs.cn/momo1938/article?id0407576070659864 1 安装包 python 可以使用qrcode来生成二维码&…...

2023第二届中国绿色钢铁国际峰会

会议背景 钢铁是当今世界上最常用的金属&#xff0c;普遍应用于世界各国基础设施建设与机械、汽车、飞机、船舶、家电等产品的生产制造中。但是&#xff0c;随着各国政府与行业净零排放目标的确立&#xff0c;钢铁行业的减排降碳也成为了关注焦点。据世界钢铁协会称&#xff0c…...

java 高考志愿填报系统Myeclipse开发mysql数据库web结构jsp编程计算机网页项目

一、源码特点 java 高考志愿填报系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql5.0…...

机器学习 vs 深度学习:了解两者的异同

在人工智能领域中&#xff0c;机器学习和深度学习是两个重要的概念。尽管它们都可以用于处理复杂的数据和任务&#xff0c;但它们在其基本原理、算法和应用方面有着显著的不同之处。在本文中&#xff0c;我们将详细介绍机器学习和深度学习的定义、原理、算法和应用&#xff0c;…...

流行的 DAW编曲软件FL Studio 21 有什么新功能?

FL Studio 21 对流行的 DAW 和音乐制作软件进行了多项更新。最重要的变化包括&#xff1a;更快、更精确的音频包络和带有自动交叉推子的增益控制&#xff1b;一个能够标记、制作自定义颜色的标签和访问在线内容的新浏览器&#xff0c;以及一个带有可视化和擦除功能的内嵌音频播…...

【Java】抽象类和接口

抽象类和接口抽象类抽象类的概念抽象类语法抽象类的注意事项抽象类的作用接口接口的概念语法规则接口使用接口注意实现多个接口接口间的继承接口使用实例给对象数组排序Clonable 接口和深拷贝浅拷贝深拷贝抽象类和接口的区别抽象类 抽象类的概念 在面向对象的概念中&#xff…...

Lora:Low-Rank Adapation of Large Language models

Lora&#xff1a;Low-Rank Adapation of Large Language modelsIntroductionMethodExperiment代码Introduction 这篇论文最初与21.06上传与arXiv&#xff0c;作者指出在当时&#xff0c;NLP的一个重要范式是先训练一个通用领域的模型然后在通过微调适应不同的领域与数据&#…...

洛谷-P8466 [Aya Round 1 A] 幻想乡扑克游戏

题目&#xff1a;P8466 [Aya Round 1 A] 幻想乡扑克游戏 题目描述&#xff1a; 题目描述 斗地主是一种使用 &#xfffd;A 到 &#xfffd;K 加上大小王的共 5454 张扑克牌来进行的游戏&#xff0c;其中大小王各一张&#xff0c;其它数码牌各四张。在斗地主中&#xff0c;牌的…...

HBase性能优化方法总结

1. 表的设计 1.1 Pre-Creating Regions 默认情况下&#xff0c;在创建HBase表的时候会自动创建一个region分区&#xff0c;当导入数据的时候&#xff0c;所有的HBase客户端都向这一个region写数据&#xff0c;直到这个region足够大了才进行切分。一种可以加快批量写入速度的方…...

Linux基础内容(16)—— 文件系统

Linux基础内容&#xff08;15&#xff09;—— 缓冲区https://blog.csdn.net/m0_63488627/article/details/129824563?spm1001.2014.3001.5501 目录 1.基础知识 2.磁盘的存储原理 1.物理结构 2.存储结构 3.逻辑结构 1.基础知识 之前介绍的全是进程打开的文件是如何执行…...

Vue自定义事件

自定义事件 ​ 通以上代码不难发现&#xff0c;数据项在Vue的实例中&#xff0c; 但删除操作要在组件中完成&#xff0c; 那么组件如何才能删除Vue实例中的数据呢?此时就涉及到参数传递与事件分发了&#xff0c; Vue为我们提供了自定义事件的功能很好的帮助我们解决了这个问题…...

Java SE 基础 (6) 第一个Java程序

开发环境已经搭建完毕&#xff0c;可以开发我们第一个Java程序了。 Java程序开发三步骤&#xff1a;编写、编译、运行。 编写Java源程序 public class HelloWord {public static void main(String[] args) {System.out.println("HelloWord!");} } 第一个 HelloWo…...

P1004 [NOIP2000 提高组] 方格取数

题目描述 设有 &#xfffd;&#xfffd;NN 的方格图 (&#xfffd;≤9)(N≤9)&#xff0c;我们将其中的某些方格中填入正整数&#xff0c;而其他的方格中则放入数字 00。如下图所示&#xff08;见样例&#xff09;: 0 0 0 0 0 0 0 0 0 0 13 0 0 6 0 0 0 0 0…...

Leetcode.1024 视频拼接

题目链接 Leetcode.1024 视频拼接 Rating &#xff1a; 1746 题目描述 你将会获得一系列视频片段&#xff0c;这些片段来自于一项持续时长为 time秒的体育赛事。这些片段可能有所重叠&#xff0c;也可能长度不一。 使用数组 clips描述所有的视频片段&#xff0c;其中 clips[i…...

Linux链表操作全解析

Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表&#xff1f;1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

应用升级/灾备测试时使用guarantee 闪回点迅速回退

1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间&#xff0c; 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点&#xff0c;不需要开启数据库闪回。…...

利用ngx_stream_return_module构建简易 TCP/UDP 响应网关

一、模块概述 ngx_stream_return_module 提供了一个极简的指令&#xff1a; return <value>;在收到客户端连接后&#xff0c;立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量&#xff08;如 $time_iso8601、$remote_addr 等&#xff09;&a…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

【决胜公务员考试】求职OMG——见面课测验1

2025最新版&#xff01;&#xff01;&#xff01;6.8截至答题&#xff0c;大家注意呀&#xff01; 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:&#xff08; B &#xff09; A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...

【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统

目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索&#xff08;基于物理空间 广播范围&#xff09;2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...