STL源码笔记之型别提取技法(2)

2024-05-04 23:32

本文主要是介绍STL源码笔记之型别提取技法(2),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.iterator_category

    (1)Input Iterator:这种迭代器所指的对象,不允许外接改变,只读。    

    (2)Output Iterator:只写。

    (3)Forward Iterator:允许“写入型”算法在此迭代器所形成的区间上进行读写操作。

    (4)Bidirectional Iterator:可双向移动。某些算法需要逆向走访某个迭代器区间,可使用Bidirectional Iterator。

    (5)Random Access Iterator:前四种迭代器只提供一部分指针的能力(前三种只支持operator++,operator--),第五种涵盖所有指针算术能力。包括p+n、p-n、p[n]、p1-p2,p1<p2。

      为了能够提供编译迭代器动态选择,STL定义了五种标记用的型别,这样我们在调用涉及到迭代器的函数时,就能选择符合相应迭代器特性的函数。五个迭代器分别为:

                  struct input_iterator_tag{};

                  struct output_iterator_tag{};

                  struct forward_iterator_tag: public input_iterator_tag{};

                  struct bidirection_iterator_tag: public forward_iterator_tag{};

                  struct random_access_iterator_tag: public bidirection_iterator_tag{};

这些class只作标记使用,不占用任何空间。

//advance()为例
//最后一个参数只是用来重载,不需要任何成员
template<class InputIterator,class Distance>
inline void__advance(InputIterator& i,Distance n,input_iterator_tag)
{while(n--)++i;}
template<class ForwardIterator,class Distance>
inline void__advance(ForwardIterator& i,Distance n,forward_iterator_tag)
{
__advance(i,n,input_iterator_tag);
}
template<class BidirectionalIterator,class Distance>
inline void__advance(BidirectionalIterator& i,Distance n,bidirectional_iterator_tag)
{
if(n>=0)while(n--)++i;
else while(n++)--i;
}
template<class RandomAccessIterator,class Distance>
inline void__advance(RandomAccessIterator& i,Distance n,random_access_iterator_tag)
{
i+=n;
}
//调用的时候,InputIterator可以是所有上面的五种迭代器之一
template<class InputIterator,class Distance>
inline void advance(InputIterator& i,Distance n)
{
//自动选择上面的四个函数
//萃取iterator_category必须在每个iterator_traits里面
__advance( i,n,iterator_traits<InputIterator>::iterator_category());
}


2.std::iterator的保证

      为了符合规范,任何迭代器都必须要相应的型别,以利于traits萃取,否则便是自别于整个STL架构,可能无法与STL组件顺利搭配。STL定义了一个标准的iterator class,每个迭代器都继承自它,这样就保证了统一行。

template<
class Category,
class T,
class Distance = ptrdiff_t,
class Pointer = T*,
class Reference = T&              
>
struct iterator{
typedef  Category     iterator_category;
typedef  T                 value_type;
typedef  Distance     difference_type;
typedef  Pointer        pointer;
typedef  Reference   reference  ;
};

      iterator class不含任何成员,纯粹型别定义,所以继承不会招致任何负担,由于后三个参数皆有默认值。故心得迭代器只需要提供两个参数即可。

template<class T>

struct ListIter:public std: iterator<std::forward_iterator_tag,Item>

{...........}

3.__type_traits

      类型粗略的讲有两种,一种是用class封转,并且它的复制拷贝很费时,比如需要深度复制,需要safe copying——即需要调用构造函数完成复制;另一种是所谓的POD(plain old data),一般是build-in类型或是c式的struct类型,这种类型复制和拷贝时只需直接复制内存块就可以了,于是有了bitwise copying或是trival construct/deconstruct/copy/assignment的概念。

      SGI STL中使用__type_traits就可以在编译期间就确定复制一个对象是调用赋值构造函数还是直接调用memcpy,从而提高效率。看SGI STL的源代码:

  1. struct __true_type {};  
  2. struct __false_type {};  
  3.   
  4. template <class type>   //primariy template  
  5. struct __type_traits {   
  6.      typedef __true_type     this_dummy_member_must_be_first;  
  7.       
  8.     typedef __false_type    has_trivial_default_constructor;  
  9.     typedef __false_type    has_trivial_copy_constructor;  
  10.     typedef __false_type    has_trivial_assignment_operator;  
  11.     typedef __false_type    has_trivial_destructor;  
  12.     typedef __false_type    is_POD_type;  
  13. };  
  14. __STL_TEMPLATE_NULL struct __type_traits<char> { //full specialization  
  15.     typedef __true_type    has_trivial_default_constructor;  
  16.     typedef __true_type    has_trivial_copy_constructor;  
  17.      typedef __true_type    has_trivial_assignment_operator;  
  18.     typedef __true_type    has_trivial_destructor;  
  19.     typedef __true_type    is_POD_type;  
  20. };  
  21. __STL_TEMPLATE_NULL struct __type_traits<int> {  
  22.     typedef __true_type    has_trivial_default_constructor;  
  23.     typedef __true_type    has_trivial_copy_constructor;  
  24.     typedef __true_type    has_trivial_assignment_operator;  
  25.     typedef __true_type    has_trivial_destructor;  
  26.     typedef __true_type    is_POD_type;  
  27. };  
接下来,看看怎样使用__type_trairt:
[cpp]  view plain copy
  1. template <class InputIterator, class ForwardIterator, class T>  
  2. inline ForwardIterator __uninitialized_copy(InputIterator first, InputIterator last,  
  3.                      ForwardIterator result, T*) {  
  4.         typedef typename __type_traits<T>::is_POD_type is_POD;  
  5.         return __uninitialized_copy_aux(first, last, result, is_POD());  
  6. }  
  7. template <class InputIterator, class ForwardIterator> inline ForwardIterator   
  8. __uninitialized_copy_aux(InputIterator first, InputIterator last,  
  9.                          ForwardIterator result, __true_type) {  
  10.         return copy(first, last, result); //STL 算法copy里面大有乾坤,针对POD类型,调用memmove,还含有iterator_trait的使用  
  11. }  
  12. template <class InputIterator, class ForwardIterator>  
  13. ForwardIterator __uninitialized_copy_aux(InputIterator first, InputIterator last,  
  14.                          ForwardIterator result, __false_type) {  
  15.         ForwardIterator cur = result;  
  16.         for ( ; first != last; ++first, ++cur)  
  17.                construct(&*cur, *first);  
  18.         return cur;  
  19.   }  
  20. }  

这篇关于STL源码笔记之型别提取技法(2)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/960331

相关文章

Python实现word文档内容智能提取以及合成

《Python实现word文档内容智能提取以及合成》这篇文章主要为大家详细介绍了如何使用Python实现从10个左右的docx文档中抽取内容,再调整语言风格后生成新的文档,感兴趣的小伙伴可以了解一下... 目录核心思路技术路径实现步骤阶段一:准备工作阶段二:内容提取 (python 脚本)阶段三:语言风格调

Java 正则表达式URL 匹配与源码全解析

《Java正则表达式URL匹配与源码全解析》在Web应用开发中,我们经常需要对URL进行格式验证,今天我们结合Java的Pattern和Matcher类,深入理解正则表达式在实际应用中... 目录1.正则表达式分解:2. 添加域名匹配 (2)3. 添加路径和查询参数匹配 (3) 4. 最终优化版本5.设计思

一文详解如何在Python中从字符串中提取部分内容

《一文详解如何在Python中从字符串中提取部分内容》:本文主要介绍如何在Python中从字符串中提取部分内容的相关资料,包括使用正则表达式、Pyparsing库、AST(抽象语法树)、字符串操作... 目录前言解决方案方法一:使用正则表达式方法二:使用 Pyparsing方法三:使用 AST方法四:使用字

利用Python快速搭建Markdown笔记发布系统

《利用Python快速搭建Markdown笔记发布系统》这篇文章主要为大家详细介绍了使用Python生态的成熟工具,在30分钟内搭建一个支持Markdown渲染、分类标签、全文搜索的私有化知识发布系统... 目录引言:为什么要自建知识博客一、技术选型:极简主义开发栈二、系统架构设计三、核心代码实现(分步解析

Java调用C++动态库超详细步骤讲解(附源码)

《Java调用C++动态库超详细步骤讲解(附源码)》C语言因其高效和接近硬件的特性,时常会被用在性能要求较高或者需要直接操作硬件的场合,:本文主要介绍Java调用C++动态库的相关资料,文中通过代... 目录一、直接调用C++库第一步:动态库生成(vs2017+qt5.12.10)第二步:Java调用C++

详解C#如何提取PDF文档中的图片

《详解C#如何提取PDF文档中的图片》提取图片可以将这些图像资源进行单独保存,方便后续在不同的项目中使用,下面我们就来看看如何使用C#通过代码从PDF文档中提取图片吧... 当 PDF 文件中包含有价值的图片,如艺术画作、设计素材、报告图表等,提取图片可以将这些图像资源进行单独保存,方便后续在不同的项目中使

Python实现无痛修改第三方库源码的方法详解

《Python实现无痛修改第三方库源码的方法详解》很多时候,我们下载的第三方库是不会有需求不满足的情况,但也有极少的情况,第三方库没有兼顾到需求,本文将介绍几个修改源码的操作,大家可以根据需求进行选择... 目录需求不符合模拟示例 1. 修改源文件2. 继承修改3. 猴子补丁4. 追踪局部变量需求不符合很

Python实现常用文本内容提取

《Python实现常用文本内容提取》在日常工作和学习中,我们经常需要从PDF、Word文档中提取文本,本文将介绍如何使用Python编写一个文本内容提取工具,有需要的小伙伴可以参考下... 目录一、引言二、文本内容提取的原理三、文本内容提取的设计四、文本内容提取的实现五、完整代码示例一、引言在日常工作和学

C++字符串提取和分割的多种方法

《C++字符串提取和分割的多种方法》在C++编程中,字符串处理是一个常见的任务,尤其是在需要从字符串中提取特定数据时,本文将详细探讨如何使用C++标准库中的工具来提取和分割字符串,并分析不同方法的适用... 目录1. 字符串提取的基本方法1.1 使用 std::istringstream 和 >> 操作符示

基于Python开发批量提取Excel图片的小工具

《基于Python开发批量提取Excel图片的小工具》这篇文章主要为大家详细介绍了如何使用Python中的openpyxl库开发一个小工具,可以实现批量提取Excel图片,有需要的小伙伴可以参考一下... 目前有一个需求,就是批量读取当前目录下所有文件夹里的Excel文件,去获取出Excel文件中的图片,并