C++标准库
为了建立数据结构和算法的一套标准,并且降低他们之间的耦合关系,以提升各自的独立性、弹性、交互操作性(相互合作性interoperability),诞生了STL(Standard Template Library 标准模板库)。
STL几乎所有的代码都采用了模板类或者模板函数,这相比传统的由函数和类组成的库来说提供了更好的代码重用机会。
- C++ Standard Library:C++标准库 (更广泛)
- Standard Template Library (STL):标准模板库(六大部件)
标准库以header files形式呈现
- C++标准库的 header files不带(.h),例如 #include>
- 新式C header files不带.h,例如 #include
- 旧式C header files(.h)仍然可用,例如 #include <stdio.h>
- 新式headers内的组件封装在namespace std中:
- using namespace std;
- using std::cout
- 旧式headers内的组件不封装於namespace “std”
重要参考网页
- cplusplus.com
- cppreference.com
- gcc.gnu.org
STL六大部件(Components)
模板编程的思想(不同于面向对象编程)
- 容器(Containers):各种数据结构,如vector、list、deque、set、map等,用来存放数据。
- 从实现角度来看,STL容器是一种class template
- 分配器(Allocators):负责容器空间的配置与管理。从实现角度看,配置器是一个实现了动态空间配置、空间管理、空间释放的class tempalte
- 算法(Algorithms):对容器数据处理,如sort、find、copy、for_each等。
- 从实现的角度来看,STL算法是一种function tempalte
- 迭代器(Iterators):扮演了容器与算法之间的胶合剂,共有五种类型。
- 从实现角度来看,迭代器是一种将operator* , operator-> , operator++,operator-- 等指针相关操作予以重载的class template。
- 所有 STL 容器都附带有自己专属的迭代器,只有容器的设计者才知道如何遍历自己的元素。
- 原生指针(native pointer)也是一种迭代器。
- 适配器(Adapters):用来修饰容器或者仿函数或迭代器接口。
- 仿函数(Functors):行为类似函数,可作为算法的某种策略。
- 从实现角度来看,仿函数是一种重载了operator() 的class 或者class template
STL六大组件的交互关系:容器通过空间配置器取得数据存储空间,算法通过迭代器存储容器中的内容,仿函数可以协助算法完成不同的策略的变化,适配器可以修饰仿函数。

#include <vector>
#include <algorithm>
#include <functional>
#include <iostream>
using namespace std;
//在下图中,我们使用了如下:
1.一个容器vector
2.使用vector时,使用分配器分配内存
3.使用vi.begin(),vi.end()即迭代器,作为算法的参数
4.使用count_if算法
5.使用仿函数less()
6.使用函数适配器来对我们算法的结果进行进一步筛选(not1, bind2nd)
int main(){
int ia[6] = {1,2,3,4,5,6};
vector<int, allocator<int>> vi(ia, ia+6); // 容器元素类型必须和分配器指明的元素类型一致
cout << count_if(vi.begin(), vi.end(), not1(bind2nd(less<int>(), 40))); // 条件 >=40
return 0;
}

STL优点
STL 是 C++ 的一部分,因此不用额外安装什么,它被内建在你的编译器之内
STL 的一个重要特性是将数据和操作分离。数据由容器类别加以管理,操作则由可定制的算法定义。迭代器在两者之间充当“粘合剂”,以使算法可以和容器交互运作
程序员可以不用思考 STL 具体的实现过程,只要能够熟练使用 STL 就 OK 了。这样就可以把精力放在程序开发的别的方面。
STL 具有高可重用性,高性能,高移植性,跨平台的优点
- 高可重用性:STL 中几乎所有的代码都采用了模板类和模版函数的方式实现,这相比于传统的由函数和类组成的库来说提供了更好的代码重用机会。
- 高性能:如 map 可以高效地从十万条记录里面查找出指定的记录,因为 map 是采用红黑树的变体实现的。
- 高移植性:如在项目 A 上用 STL 编写的模块,可以直接移植到项目 B 上。
ps. namespace 命名空间
- 在一个namespace里面的任何定义以及变量等都不会和其他的namespace冲突
- 每一个namespace所需的头文件放在namespace开始之前(不包含在namespace中)。
- 并且头文件多次包含不会有问题(有#pragma once 、#ifndef #endif等机制)
- 变量的声明和定义 一般都放在最开始部分。
- 但是有时候也可以在用到该变量的时候再进行定义。如果不好找,可以采取一个技巧:把所有定义/声明的语句都采取省略缩放的做法。
版权声明:本文为beyon_sir原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。