background image

如果你有个 vector v,而你需要得到一个只想 v 中的数据的指针,从而可把数据作为数组

来对才,那么只需要使用&v[0]就可以了,也可以用&*v.begin(),但是不好理解。

对于 string s,随应的形式是 s.c_str()。

如果想用来自 C API 的数据来初始化一个 vector,那么你可以利用 vector 和数组的内存布

局兼容性,先把数据写入到 vector 中,然后把数据拷贝到期望最终写入的 STL 容器中。

第 17

条:使用 swap

技巧 出去多余的容量。

vector<Contestant>(contestants).swap(contestants);

表达式 vector<Contestant>(contestants)创建一个临时的矢量,它是 contestants 的拷贝:这是

 

由 vector 的拷贝构造函数来完成的。然而,vector 的拷贝构造函数只为所拷贝的元素分配

所需要的的内存,所以这个临时矢量没有多余的容量。然后我们把临时矢量中的数据和
contestants 中的数据作 swap 操作,在这之后,contestants 具有了被去除之后的容量,即原

先临时变量的容量,而临时变量的容量则变成了原先 contestants 臃肿的容量。到这时,临

时矢量被析构,从而释放了先前为 contestants 所占据的内存。

同样的技巧对 string 也实用:
string s;
...
string(s).swap(s);

第 18 条:避免使用 vector<bool>。

作为 STL 容器,vector<bool>只有两点不对。首先,它不是一个 STL 容器;其次,它并不

存储 bool。除此以外,一切正常。因此最好不要使用它,你可以用 deque<bool>和 bitset 替

代。vector<bool>来自一个雄心勃勃的试验,代理对象在 C++软件开发中经常会很有用 。
C++标准委员会的人很清楚这一点,所以他们决定开发 vector<bool>,以演示 STL 如果

 “

支持 通过代理对象来存取其元素的的容器 。他们说,C++标准中有了这个例子,于是,

人们在实现自己的基于代理的容器时就有了一个参考。然而他们却发现,要创建一个基于

代理的容器,同时又要求它满足 STL 容器的所有要求是不可能的。由于种种原因,他们失

败了的尝试被遗留在标准中。

第 3

 

章 关联容器

第 19 条:理解相等(equality)和等价(equivalence)的区别。

标准关联容器总是保持排列顺序的,所以每个容器必须有一个比较函数(默认为

less)。等价的定义正是通过该比较函数而确定的。相等一定等价,等价不一定相等。

第 20 条:为包含指针的关联容器指定比较类型。

每当你创建包含指针的关联容器时,容器将会按照指针的值(就是内存地址)进行排序,

绝大多数情况下,这不是你所希望的。

第 21 条:总是让比较函数在等值情况下返回 false。

现在我给你演示一个很酷的现象。创建一个 set,用 less_equal 作为它的比较类型,然后把
10 插入到该集合中:
set<int, less_equal<int> > s; //s 用"<=" 来排序
s.insert(10);
s.insert(10);

对于第二个 insert,集合会检查下面的表达式是否为真:
!(10a <= 10b) && !(10b <= 10a); //检查 10a 和 10b 是否等价,结果是!(true) && !(true) 为
false

结果集合中有两个 10!

从技术上讲,用于对关联容器排序的比较函数必须为他们所比较的对象定义个 严格的弱

序化 (strict weak ordering)。

第 22 条:切勿直接修改 set 或 multiset 中的键。

如果你不关心可移植性,而你想改变 set 或 multiset 中元素的值,并且你的 STL 实现(有

的 STL 实现中,比如 set<T>:: iterator 的 operator*总是返回 const T&,就不能修改了)允