Genericity-STL 大系
泛型和模版的区别

泛型和模版的区别
泛型是概念, 模板是泛型的实现
泛型编程让你编写完全⼀般化并可重复使⽤的算法,其效率与针对某特定数据类型⽽设计的算法相同。
泛型编程的代表作品STL是⼀种⾼效、泛型、可交互操作的软件组件。
所谓泛型(Genericity),是指具有在多种数据类型上皆可操作的含意,与模板有些相似。
STL巨⼤,⽽且可以扩充,它包含很多计算机基本算法和数据结构,⽽且将算法与数据结构完全分离,其中算法是泛型的,不与任何特定数据结构或对象类型系在⼀起。
STL以迭代器(Iterators)和容器(Containers)为基础,是⼀种泛型算法(Generic Algorithms)库,容器的存在使这些算法有东西可以操作。
STL包含各种泛型算法(algorithms)、泛型指针(iterators)、泛型容器(containers)以及函数对象(function objects)。
STL并⾮只是⼀些有⽤组件的集合,它是描述软件组件抽象需求条件的⼀个正规⽽有条理的架构。
STL源码剖析学习笔记

STL源码剖析学习笔记
deque的迭代器
deque的迭代器除了⼀些型别定义,主要有以下四个数据成员:
typedef T** map_pointer;
T* cur;
T* first;
T* last;
map_pointer node;
deque的主要的数据成员:
protected:
iterator start;
iterator finish;
map_iterator map;
size_type map_size;
可以看到deque维护了两个迭代器。
迭代器的node指向连续空间map某⼀个元素,first和last指向某个缓冲区的起始和结束,⽽cur指向当前元素。
deque的两个迭代器的cur有特别意义,start.cur指向第⼀个缓冲区的第⼀个元素的位置,finish.cur指向最后缓冲区的最后⼀个元素的位置。
所以两个迭代器的first,last和node很可能完全⼀样(同⼀个缓冲区),cur才是区分他们的根本。
⽽迭代器其实提供给外界的假象就是它是⼀个连续空间,iterator的⾏为就像是cur的⾏为。
所以iterator ite,在++时,只需把cur++即可;在两个迭代器相减时只需把两者的cur 相减;⽐较两个迭代器是否相等时,只需看⼆者cur是否相等,当然,以上的⼤前提是⼀定要考虑是否跨缓冲区间!即迭代器默默维护的first,last,node。
要注意的是start和finish元素增长的⽅向是相反的,⼀个是last---->first,⼀个是first----->last。
STL经典实用教程

1.STL(模板库)基本概念1.1基本概念STL详细的说六大组件–容器(Container)1.2容器在实际的开发过程中,数据结构本身的重要性不会逊于操作于数据结构的算法的重要性,当程序中存在着对时间要求很高的部分时,数据结构的选择就显得更加重要。
经典的数据结构数量有限,但是我们常常重复着一些为了实现向量、链表等结构而编写的代码,这些代码都十分相似,只是为了适应不同数据的变化而在细节上有所出入。
STL 容器就为我们提供了这样的方便,它允许我们重复利用已有的实现构造自己的特定类型下的数据结构,通过设置一些模版类,STL容器对最常用的数据结构提供了支持,这些模板的参数允许我们指定容器中元素的数据类型,可以将我们许多重复而乏味的工作简化。
容器部分主要由头文件<vector>,<list>,<deque>,<set>,<map>,<stack> 和<queue>组成。
对于常用的一些容器和容器适配器(可以看作由其它容器实现的容器),可以通过下表总结一下它们和相应头文件的对应关系。
容器的概念用来管理一组元素容器的分类序列式容器(Sequence containers)每个元素都有固定位置--取决于插入时机和地点,和元素值无关。
vector、deque、lista[3];a[0]关联式容器(Associated containers)元素位置取决于特定的排序准则,和插入顺序无关set、multiset、map、multimap1.3迭代器迭代器从作用上来说是最基本的部分,可是理解起来比前两者都要费力一些。
软件设计有一个基本原则,所有的问题都可以通过引进一个间接层来简化,这种简化在STL中就是用迭代器来完成的。
概括来说,迭代器在STL中用来将算法和容器联系起来,起着一种黏和剂的作用。
几乎STL提供的所有算法都是通过迭代器存取元素序列进行工作的,每一个容器都定义了其本身所专有的迭代器,用以存取容器中的元素。
第12章 标准模板库STL

(1)向量的定义和初始化 vector类有4种构造函数: vector(); 默认构造函数,它构造一个空的vector,其大小为零。 例如, vector <elementType> vecList; 使用默认构造函 数创建一个没有任何元素的空向量vecList。vecList. size()=0。 vector(size_type n,const T&value=T()); n const 构造一个初始放入n个值为value的元素的vector。第1个 参数为vector初始化的大小,第2个参数是vector中每个对象的 初始值,默认为T()构造的对象。 例如, vector <elementType> vecList(size); 创建一个 大小为size的向量vecList,并使用elementType类的默认构造 函数初始化该向量。 vector <elementType> vecList(n,elem); 创建一个大小 为n的向量vecList,该向量中所有的n个元素都初始化为elem。
STL函数适配器 STL函数对象
STL最主要的一个特点:数据结构和算法的分离。 容器是像链表,向量、栈、队列之类的数据结构,并按类 模板方式提供; 算法是函数模板,用于操作容器中的数据。 由于STL以模板为基础,所以能用于任何数据类型和结构。 实际上,可以认为STL是以容器和迭代器为基础的一种泛 型算法(Generic Algorithms)库。 所谓泛型(Genericity)是指能够在多种数据类型上进行 操作,在泛型化程序设计思想里,大部分基本算法被抽象,被 泛化,独立于与之对应的数据结构,用于以相同或相近的方式 处理各种不同情形。
包含vector类的头文件是<vector>。所以,如果要在程 序里使用向量容器,就要在程序中包含下面语句: #include <vector> 在定义向量类型对象时,必须指定该对象的类型。 例如: vector<int> intVec; 将intVec声明为一个元素类型为int的向量容器对象。 vector<string> stringVec; 将stringVec声明为一个元素类型为string的向量容 器对象。 Vector提供的成员函数主要列举如书296页表12-1所示。
stl容器知识点总结

stl容器知识点总结一、STL容器的种类STL中的容器主要分为序列式容器(Sequence Containers)和关联式容器(Associative Containers)两大类。
序列式容器包括vector、deque、list、forward_list以及array等,而关联式容器则包括set、map、multiset、multimap和unordered_set、unordered_map、unordered_multiset、unordered_multimap等。
1. 序列式容器(1)vector:动态数组,支持随机存取,可以在尾部进行快速插入和删除操作,但在中间和头部的插入和删除效率比较低。
(2)deque:双端队列,支持随机存取,同时在头部和尾部进行快速插入和删除操作,但在中间的插入和删除效率比较低。
(3)list:双向链表,支持在任意位置进行快速插入和删除操作,但不支持随机存取。
(4)forward_list:单向链表,与list相似,但只支持单向的迭代器访问。
(5)array:固定大小的数组,提供与普通数组相似的访问和操作方式。
2. 关联式容器(1)set:集合,不允许重复的元素,并且会自动排序。
(2)map:映射,每个元素都含有一个键值对,并且键是唯一的,自动排序。
(3)multiset:多重集合,允许重复的元素,并且会自动排序。
(4)multimap:多重映射,允许重复的键值对,并且会自动排序。
(5)unordered_set:无序集合,不允许重复的元素,内部实现采用哈希表。
(6)unordered_map:无序映射,每个元素都含有一个键值对,键是唯一的,内部实现采用哈希表。
(7)unordered_multiset:无序多重集合,允许重复的元素,内部实现采用哈希表。
(8)unordered_multimap:无序多重映射,允许重复的键值对,内部实现采用哈希表。
以上就是STL中的主要容器种类,每种容器都有各自的特性和适用场景,在实际开发中需要根据具体的需求选择合适的容器进行使用。
java+泛型

浅谈Java泛型编程原文地址:/thread.jspa?messageID=154504我原本想全文翻译Generics in the Java Programming Language,但是功力不够,太耗时间。
于是乎按照原文的框架,翻了一些再加上自己写的一点东西。
第一次写文,如有谬误还清指出~~谢谢!浅谈Java泛型编程1 引言在JDK 1.5中,几个新的特征被引入Java语言。
其中之一就是泛型(generics)。
泛型(generics,genericity)又称为“参数类型化(parameterized type)”或“模板(templates)”,是和继承(inheritance)不同而互补的一种组件复用机制。
继承和泛型的不同之处在于——在一个系统中,继承层次是垂直方向,从抽象到具体,而泛型是水平方向上的。
当运用继承,不同的类型将拥有相同的接口,并获得了多态性;当运用泛型,将拥有许多不同的类型,并得以相同的算法作用在它们身上。
因此,一般说来,当类型与实现方法无关时,使用泛型;否则,用继承。
泛型技术最直接联想到的用途就是建立容器类型。
下面是一个没有使用泛型技术的例子:List myIntList = new LinkedList();// 1myIntLikst.add(new Integer(0));// 2Integer x = (Integer)myIntList.iterator().next();// 3显然,程序员知道究竟是什么具体类型被放进了myIntList中。
但是,第3行的类型转换(cast)是必不可少的。
因为编译器仅仅能保证iterator返回的是Object类型。
要想保证将这个值传给一个Integer类型变量是安全的,就必须类型转换。
除了使代码显得有些混乱外,类型转换更带来了运行时错误的可能性。
因为程序员难免会犯错误。
使用了泛型技术,程序员就可以确切地表达他们的意图,并且把myIntList限制为包含一种具体类型。
柱面stl格式 -回复

柱面stl格式-回复什么是柱面STL格式?柱面STL格式是一种三维模型文件格式,用于存储和交换三维模型数据。
它是STL(Surface Tessellation Language,表面镶嵌语言)格式的一种变体,不同于传统的STL格式,柱面STL格式专门适用于描述柱面形状的对象。
柱面STL格式的特点是使用特定的数据结构和存储方式来表示柱面模型,使其更加高效和准确。
在柱面STL格式中,模型由一系列的三角面片组成,每个面片都由三个顶点和法线向量定义。
与传统的STL格式不同的是,柱面STL格式还包含了额外的轴向信息,以便准确地表示柱面形状。
在柱面STL格式中,模型的基本信息包括柱面的轴向、半径、高度以及分割数。
轴向表示柱面的旋转轴,可以是任意方向。
半径表示柱面的横截面半径,决定了柱面的粗细。
高度表示柱面的长度,决定了柱面的高度。
分割数表示柱面的切割份数,决定了柱面的平滑程度。
柱面STL格式的优势在于能够准确地描述柱面形状,使得模型更加真实和可靠。
传统的STL格式只能近似地表示柱面,通常需要使用更多的三角面片来模拟柱面造成文件大小增大以及不必要的计算开销。
而柱面STL格式通过轴向信息和分割数的设定,可以更加精确地表示柱面的外形,减少了面片数量和计算开销。
在实际应用中,柱面STL格式广泛用于制造业、建筑业和计算机图形学领域。
制造业中,柱面STL格式常用于数控机床的刀具路径生成、数值模拟分析等工作中。
建筑业中,柱面STL格式常用于建筑设计和模拟施工等工作中。
计算机图形学领域中,柱面STL格式常用于三维建模、渲染和动画等工作中。
总结一下,柱面STL格式是一种专门用于描述柱面形状的三维模型文件格式。
它通过特定的数据结构和存储方式,准确地表示柱面的轴向、半径、高度和分割数等信息。
柱面STL格式具有高效和准确性的优势,广泛应用于制造业、建筑业和计算机图形学领域等不同的领域中。
C++模板与STL

容器概述
对象被插入容器中时,被插入的是对象的一个 复制品。 许多算法,比如排序,查找,要求对容器中的 元素进行比较,所以,放入容器的对象所属的 类,还应该实现 == 和> < 运算符。
顺序容器简介
1) vector 头文件 <vector> 实际上就是个动态数组。随机存取任何元素都能在常数 时间完成。在尾端增删元素具有较佳的性能。 2) deque 头文件 <deque> 也是个动态数组,随机存取任何元素都能在常数时间完 成(但性能次于vector)。在两端增删元素具有较佳的性 能。 3) list 头文件 <list> 双向链表,在任何位置增删元素都能在常数时间完成。 不支持随机存取。 上述三种容器称为顺序容器,是因为元素的插入位置同 元素的值无关。
一般先写一个特殊版本的函数 运行正确后,改成模板函数
27
STL中的几个基本概念
容器:可容纳各种数据类型的数据结构。 迭代器:可依次存取容器中元素的东西 算法:用来操作容器中的元素的函数模板。例如,STL 用sort()来对一个vector中的数据进行排序,用find()来搜 索一个list中的对象。
模板引子
1. 假如设计一个求两参数最大值的函数,在实践中我们可 能需要定义四个函数: int max ( int a , int b ) { return ( a > b ) ? a , b ; } long max ( long a , long b ) { return ( a > b ) ? a , b ;} double max ( double a , double b ) { return ( a >b)? a , b ; } char max ( char a , char b ) { return ( a > b ) ? a , b ;} 2.这些函数几乎相同,唯一的区别就是形参类型不同
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
【Genericity/STL 大系】《程序员》2001.02作者简介:侯捷,台湾计算机技术作家,着译评兼擅。
常着文章自娱,颇示己志。
个人网站:北京镜站:/expert/jjhou如果有一项技术,可以让你的程序代码处理各种不同的数据型别,甚至是目前未知的资料型别,你喜欢吗?我会欣喜若狂。
基本上这就是「可复用性(reusibility)」的表现。
当我们有新的数据型态产生,而过去完成的码完全无需修改即可沿用,不正是一种完美的「可复用性」吗?面向对象技术中的多型(polymorphism),以及泛型技术中的泛型(genericity)都可以达到这个目标。
它们的字义,也明白标示出其特色。
对大多数人而言,polymorphism(多型技术)早已如雷灌耳,genericity(泛型技术)则稍感陌生。
这是一个你有必要尽快进入的重要领域。
●勤前教育数年前我第一次接触泛型程序设计(generic programming)与 STL(Standard Template Library)的时候,就深深被它吸引。
虽然那时候我还不怎么了解 STL 里头一大堆的术语像是 container、iterator、adaptor、function object、allocator…。
甚至连泛型技术深度依赖的基本技法 C++ template,当时的我都还只一知半解,但光只「泛型」这两个字就够把我吸引到那个世界里面了。
但愿我这么说不至于误导你把泛型程序设计和 STL 划上等号。
泛型概念滥觞于 Doug McIlroy 于 1968 年发表的一篇著名论文 "Mass Produced Software Components",那篇论文提出了 "reusable components"(可复用软件组件,又称为软件积木或软件 IC)的愿景。
过去数十年中,泛型技术仍属于研究单位中的骄客,实作产品付之阙如。
直到 C++ 不断加强 template 机制,并将 Alexander Stepanov 创作的 STL 纳入标准,泛型技术才终于在标准数据结构和标准算法领域中有一套可被大众运用的实作品出现,向现实跨一大步。
让我们先复习一下。
下面是多型的标准形式:void func(Shape* ps) // Shape 是某个class 继承体系的基础类别{// ...ps->draw(); // draw() 是个虚拟函式(virtual function)}func() 的呼叫者可以自由传入 Shape 继承体系下任何一个 Shape 衍生类别的对象指针,func() 函式所唤起的将是实际传入之对象(指针)所对应的那个 draw() 虚拟函式。
这种写法所带来的好处是,即使将来 Shape 继承体系衍生出前所未见的子型别,只要该子型别本身提供了 draw() 虚拟函式,上面这个 func() 就完全不必更改,可继续使用。
那么,泛型又是什么呢?简单地说,这是一种「将数据型别参数化」的思维模式。
C++ 的template 机制就是泛型技术的一个具体载具。
在 C++ 中,不论 functions 或是 classes,皆可将其中所需要的数据型别以一个保留器(placeholder)代表,这个保留器亦即所谓的template 参数。
例如 function template:template<typename T1, typename T2)void func(T1 param1, T2 param2) { /* ... */ }或是 class template:template<typename T1, typename T2)class A { /* ... */ }从此,一旦程序中使用上述的 func() 或 class A,例如:func(5, 2.3);A<int, double> a;编译程序即根据 function template 的函式自变量(上例的 5 和 2.3),或根据被我们明白标示出来的 class template 自变量(上例的 int 和 double),自动推导出一份function 实体或 class 实体。
这个所谓的具现化动作(instantiation)在编译期就完成,不会增加执行期的成本。
关于 template 的详细语法与性能,请参考任何一本完备的 C++ 百科型书籍。
以上这种「将数据型别参数化,再由编译程序视使用当时的情况,为我们完成实体具现化」的概念,即是泛型的实际展现。
template 是 C++ 语言中支持泛型概念的一个工具,而 STL 则是泛型概念的一套实作品。
从学理上来说,STL 其实是一套严谨的 "concepts" 分类学。
这里所谓的concepts有其严谨定义,意指「对某种型别的某些条件需求」。
满足这些条件之型别,称为该concept的一个model。
举个例子,如果我们能够复制型别为 T 之对象,并可以将数值指派给 T 型别的变量身上,那么型别 T 便符合Assignable这一concept,而 T 便是Assignable的一个model。
STL 的六大组件 containers, algorithms, iterators, function objects, allocators, adaptors, 全都是concepts,实作品如 vector, list, sort(), swap() 等等 templates, ... 全都是model s。
这样的学理概念,对大部份人勿宁是不可承受之重。
大部份人只着眼 STL 的实用性,因为STL 非常好用,弹性非常大,执行效率也很理想,可大幅提升软件开发效率。
从实作的角度来看,以各种方式完成,符合 STL concepts 需求之各种 C++ classes 和 C++ functions,就是大家一般印象中的 STL,它们实际存在于各个相应的含入档中,如<vector>,<functional>, <algorithms>.●剖析 STL任何学习,如果直接从抽象思维开始,对大部份人是一件困难的工作。
通常我们需要一个具体可操作的东西,慢慢再由具象操作转为抽象思考。
那么,先学会使用 STL,应该是学习泛型思维的最好途径。
事实上,自从 STL 以及整个 C++ 标准链接库定案之后,很多专家,包括 Bjarne Stroustrup,都认为 C++ 程序语言的教学,首先应从如何使用标准链接库(含 STL)开始。
我当然无法在这篇文章中告诉你 STL 乃至整个标准链接库的用法。
但是我可以给你一些概念,让你知道 STL 的架构。
STL 是一个完全以 template 技术完成的链接库。
它构成了 C++ 标准链接库的绝大部份骨干—粗略估计应该占 80% 以上的面积。
STL 有六大组件(components):1 containers(容器),各种基本数据结构如vector, list, deque, set, map…,共约11 种。
其中有些亦被归类为 adaptors。
2 algorithms(算法),各种基本算法如sort, search, copy, erase…,共约 70 个。
3 iterators(迭代器):应用于容器与算法身上的一种泛型指标,扮演两者间的胶着剂。
[Gamma95]对于 iterator 这种设计样式(design pattern)的定义是:提供一种方法,俾得依序巡访某个聚合对象(容器)所含的各个元素,而又不需曝露该聚合对象的内部表述方式。
STL 共提供了五种 iterators 型态,以及各种衍生变化。
Iterator 是 STL 中最重要最抽象的一个组件,它使容器与算法可以各自独立发展,这是一种突破性的观念。
不论就实作技术或抽象观念,iterator 都是 STL 中最关键的成份。
了解了 iterators,也就进入了 STL 的大门。
4 function object:行为类似 function,但其实是一种 object。
以实作技术而言,这是一个改写了 "call operator" 的 class。
STL 提供 15 个现成的 function objects。
5 adaptors(调适器):用来改变(修饰)其他组件的接口。
[Gamma95]对于 adaptor 这种设计样式(design pattern)的定义是:将一个 class 的接口转换为另一个 class 的接口,使原本因接口不兼容而不能合作的 classes,可以一起运作。
在 STL 中,改变function object 接口者,称为 function adaptor,改变 container 接口者,称为container adaptor。
改变 iterator 接口者,称为 iterator adaptor。
例如 STL 提供的两个容器 queue 和 stack,其实都只不过是 adaptor,修饰了 deque 的界面而成就出另一种容器风貌。
6 allocator(内存配置器):容器空间配置系统。
STL 提供有现成的 allocator。
下面这个例子,用上了 STL 的所有六种组件,目的是找出某个数列之中数值大于 40 的元素个数,答案为 4。
从这个例子,你可以看到 STL 不同组件间的接合,发展到了一个怎样灵活的程度,像乐高积木一样,有无限可能。
#include <algorithm>#include <functional>#include <vector>#include <iostream>using namespace std;int main(){int ia[ ] = { 27, 210, 12, 47, 109, 83, 40 };vector<int, allocator<int> > vec( ia, ia+7 );cout << count_if(vec.begin(), vec.end(),not1(bind2nd(less_equal<int>(), 40)));return 0;}// vector 是一个STL 容器// count_if 是一个STL 算法// not1 和bind2nd 都是STL function adaptors// less_equal<> 是一个STL function object// allocator<> 是一个STL 内存配置器// vec.begin() 和vec.end() 分别传回两个iterator,指向容器vec 的头尾。