标准模板库
标准模板库(英文:Standard Template Library,缩写:STL),是一个C++软件库,大量影響了C++标准程序库但並非是其的一部分。其中包含4个组件,分别为算法、容器、函数、迭代器。[1]
模板是C++程序设计语言中的一个重要特征,而标准模板库正是基于此特征。标准模板库使得C++编程语言在有了同Java一样强大的类库的同时,保有了更大的可扩展性。
目录
1 歷史
2 內容
2.1 容器
2.2 迭代器
2.3 算法
2.4 函数对象
2.5 适配器(Adaptor)
3 與C++標準程式庫的差異
4 参考文献
5 参见
6 外部連結
歷史
标准模板库係由Alexander Stepanov創造於1979年前後,這也正是比雅尼·斯特勞斯特魯普創造C++的年代。
雖然David R. Musser於1971年開始即在計算機幾何領域發展並倡導某些泛型程序設計觀念,但早期並沒有任何程式語言支援泛型程序設計。第一個支援泛型概念的語言是Ada。[來源請求] Alex和Musser曾於1987開發出一套相關的Ada library.
标准模板库設計人Stepanov早期從事教育工作,1970年代研究泛型程序設計,那時他與其同事一起在GE公司開發出一個新的程序語言——Tecton。
1983年,Stepanov先生轉至Polytechnic大學教書,繼續研究泛型程序設計,同時寫了許多Scheme的程序,應用在graph與network的演算法上,1985年又轉至GE公司專門教授高階程序設計,並將graph與network的Scheme程式,改用Ada寫,用了Ada以後,他發現到一個動態(dynamically)类型的程序(如Scheme)與強制(strongly)类型的程序(如Ada)有多麼的不同。
在動態类型的程序中,所有类型都可以自由的轉換成別的类型,而強制类型的程序卻不能。但是,強制类型在出錯時較容易發現程序錯誤。
1988年Stepanov先生轉至HP公司執行開發泛型程序庫的工作。此時,他已经认识C語言中指標(pointer)的威力,他表示一個程序员只要有些許硬件知识,就很容易接受C語言中指標的觀念,同時也瞭解到C語言的所有数据結構均可以指標間接表示,這點是C與Ada、Scheme的最大不同。
Stepanov並認為,雖然C++中的繼承功能可以表示泛型設計,但終究有個限制。雖然可以在基礎类型(superclass)定義算法和接口,但不可能要求所有物件皆是繼承這些,而且龐大的繼承體系將減低虛擬(virtual)函數的執行效率,這便違反的前面所說的「效率」原則。
到了C++模板觀念,Stepanov參加了許多有關的研討會,與C++之父Bjarne討論模板的设计細節。如,Stepanov認為C++的函數模板(function template)應該像Ada一樣,在声明其函數原型後,應該显式的声明一个函數模板之实例(instance);Bjarne則不然,他認為可以透過C++的重載(overloading)功能來表達。
Stepanov想像中的函數模板:
in *.hpp
template<class T>
T square(T x) { return x*x; }
in *.cpp
double square(double);
cout << square(3.3);
int square(int);
cout << square(3);
Bjarne認為的函數模板:
in *.hpp
template<class T>
T square(T x) { return x*x; }
in *.cpp
cout << square(3.3);
cout << square(3);
幾經爭辯,Stepanov發現Bjarne是對的(參考侯俊傑《标准模板库講座·第三章》)。事後Stepanov回想起來非常同意Bjarne的作法。
| “ | template 引數推導機制(arguments deduction ,在标准模板库中佔非常重要的角色。Alexander Stepanov(标准模板库創造者)在與Dr. Dobb's Journal進行的訪談中說道『1992 我重回generic-library的開發工作。這時候C++有了template 我發現Bjarne完成了一個非常美妙的設計。之前我在Bell Lab曾參與數次template的相關設計討論,並且非常粗暴地要求Bjarne應該將C++ template設計得儘可能像Ada generics那樣。我想由於我的爭辯是如此地粗暴,他決定反對。我瞭解到在C++中除了擁有template classes之外還擁有template functions的重要性。然而我認為template function應該像Ada generics一樣,也就是說它們應該是显式实例,Bjarne沒有聽進我的話,他設計了一個template function機制,其中的template是以一個重載化機制 | ” |
事實上,C++的模板,本身即是一套複雜的巨集語言(macro language),巨集語言最大的特色為:所有工作在編譯時期就已完成。显式的声明函數模板之实例,與直接透過C++的多載功能隱式声明,結果一樣,並無很大區別,只是前者加重程序员的負擔,使得程式變得累贅。
1992年Meng Lee加入Alex的專案,成為另一位主要貢獻者。
1992年,HP泛型程序庫計畫結束,小組解散,只剩下Stepanov先生與Meng Lee小姐(她是東方人,标准模板库的英文名稱其實是取STepanov與Lee而來[2]),Lee先前研究的是編譯器的製作,對C++的模板很熟,第一版的标准模板库中許多程式都是Lee的傑作。
1993年,Andy Koenig到史丹佛演講,Stepanov便向他介紹标准模板库,Koenig聽後,隨即邀請Stepanov參加1993年11月的ANSI/ISO C++標準化會議,並發表演講。
Bell實驗室的Andrew Koenig於1993年知道标准模板库研究計劃後,邀請Alex於是年11月的ANSI/ISO C++標準委員會會議上展示其觀念。並獲得與會者熱烈的迴應。
1994年1月6日,Koenig寄封電子郵件給Stepanov,表示如果Stepanov願意將标准模板库的說明文件撰寫齊全,在1月25日前提出,便可能成為標準C++的一部份。Stepanov回信道:"Andy, are you crazy?" 。 Koenig便說:"Well, yes I am crazy,but why not try it?"。
Alex於是在次年夏天在Waterloo舉行的會議前完成其正式的提案,並以百分之八十壓倒性多數,一舉讓這個巨大的計劃成為C++ Standard的一部份。
标准模板库於1994年2月年正式成為ANSI/ISO C++的一部份,它的出現,促使C++程序员的思維方式更朝向泛型编程(generic program)發展。
內容
STL 将“在数据上执行的操作”与“要执行操作的数据分开”,分别以如下概念指代:
- 容器:包含、放置数据的地方。
- 迭代器:在容器中指出一个位置、或成对使用以划定一个区域,用来限定操作所涉及到的数据范围。
- 算法:要执行的操作。
容器
标准模板库包含了序列容器(sequence containers)與關聯容器(associative containers)。
| 資料容器 | 描述 |
|---|---|
| 序列容器 - 有序集 | |
vector | 动态数组,兼容C语言数组。vector可以如同陣列一樣的存取方式,例如使用下標(operator)運算子,並記得自己的長度資訊(size),您也可以使用物件的方式來存取vector(push_back、pop_back)。使用vector可以輕易地定義多維可調整型陣列(std::vector<std::vector<...> >)。要使用vector,必須含入vector表頭檔。vector可在O(1)内完成在末尾插入 / 移除元素,但在vector中间或开头插入/移除元素,则需要消耗O(n)时间。 |
list | list容器是一個有序(Ordered)的資料結構(循序容器),每个元素中存储着上一个元素和下一个元素的地址(指针),因此是一个双向链接的链表。与vector相比,其元素的访问速度较慢,而在已知元素位置的情况下,插入和删除速度较快。STL容器中唯一支持事务语义。 |
forward_list (单向链表) | list的单链表版,去掉了一些操作。 |
deque (双端队列) | 可看做为能在常量时间内完成向开头或结尾插入或删除元素的vector,但是修改之后,其迭代器的有效性就无法得到保障。 |
array | 只能在初始化时指定大小的数组,可视为内置数组的封装。 |
关联容器 - 无序集 | |
set | 不重复元素的集合。 |
multiset | 跟set具有相同功能,但允許重複的元素。 |
map | 关联数组,每个元素含有两个数据项,map将一个数据项映射到另一个数据项中。 |
multimap | 跟map具有相同功能,但允許重複的鍵值。 |
unordered_set unordered_multiset unordered_map unordered_multimap | 分别类似于集合、多重集合、映射、多重映射,但使用哈希表实现。它的键(Keys)没有排序(operator<),相反必须存在一个从键类型到size_t的哈希函数、且要求键之间可以判等(operator==)。自C++11起进入语言标准。 |
| 其他类型的容器 | |
bitset | 存储系列位类似的固定大小的布尔向量。实现按位运算,没有迭代器,不是序列。可视为std::array<bool, N>。若需要改变序列长度,可用std::vector<bool>。 |
valarray | 数值类型的std::vector。牺牲泛型能力而专为数值计算做了优化,例如在数组上的sin操作可对数组内所有数值取正弦。有些实现会对std::valarray应用向量指令等优化手段。 一个观点是里面全是数值类型的valarray才是数学意义上的向量,而可以泛型的vector更该叫array——编程语言中的数组。 |
迭代器
迭代器是泛化的指针,通过使用迭代器,开发者可以操作数据结构而无需关心其内部实现。根据迭代器的操作方式的不同,迭代器分为五种[3]:
- 输入迭代器
- 输出迭代器
- 前向迭代器
- 双向迭代器
- 随机访问迭代器
算法
STL提供了一些常见 的算法,如排序和搜索等。这些算法与数据结构的实现进行了分离。因此,用于也可对自定义的数据结构使用这些算法,只需让这些自定义的数据结构拥有算法所预期的迭代器。[4]。
函数对象
狭义的函数对象即重载了操作符()的类的实例,而广义来讲所有可用 x(...) 形式调用的 x 都可称为函数对象、或曰可调用对象。[5]。
适配器(Adaptor)
适配器为一个模板类,用于提供接口映射。[6]。
與C++標準程式庫的差異
一個常見的誤解是STL是C++標準程式庫的一部分,但事實上並非如此。例如hash table的資料結構實作在STL中有<hash_map>模板可供調用,但C++標準程式庫一直到C++11才加入了<unordered_map>。參見无序关联容器_(STL)。
参考文献
^ Holzner, Steven. C++ : Black Book. Scottsdale, Ariz.: Coriolis Group. 2001: 648. ISBN 1-57610-777-9.The STL is made up of containers, iterators, function objects, and algorithms
^ # Al Stevens Interviews Alex Stepanov.After all, STL stands for Stepanov and Lee...
^ Alexander, Stepanov. The Standard Template Library (PDF): 6. 1995.Depending on the operations defined on them, there are five categories of iterators: input iterators, output iterators, forward iterators, bidirectional iterators and random access iterators.
^ Alexander, Stepanov. The Standard Template Library (PDF): 41. 1995.
^ Alexander, Stepanov. The Standard Template Library (PDF): 14. 1995.
^ Alexander, Stepanov. The Standard Template Library (PDF): 55. 1995.
参见
- C++標準程式庫
外部連結
C/C++ reference includes a section on the STL
STL programmer's guide official guide from SGI
Bjarne Stroustrup on The emergence of the STL (Page 5, Section 3.1)
Apache stdcxx portable Open Source implementation based on Rogue Wave STL
STLport multiplatform STL implementation
Dinkumware commercial STL implementation (ships with Visual C++ and several other compilers)- Rogue Wave STL Class Reference
MPTL shared-memory parallel extension of the STL using the Native POSIX Thread Library。
STXXL: an STL implementation for external memory.
STLSoft libraries:open-source, 100% header-only, C/C++ libraries of technology-specific facades and STL extensions.
| ||||||||||||||||||||||||||

Comments
Post a Comment