容器

1、为了创建一个容器为另一个容器的拷贝,两个容器的类型及其元素类型必须匹配。不过,当传递迭代器参数来拷贝一个范围时,就不要求容器类型是相同的了。而且新容器和原容器中的元素类型也可以不同,只要能将要拷贝的元素转换为要初始化的容器中的元素类型即可。

2、与内置数组不同,标准库array类型允许赋值,赋值号两边的运算对象必须具有相同的类型。注意大小也是array的数据类型的一部分。array<int, 10> a = {0};正确,所有元素都初始化为0。a = {0};错误,此处为赋值语句,a大小为10,右侧列表大小为1,类型不匹配。

3、swap(c1, c2);或者c1.swap(c2);交换c1c2中的元素,c1和c2必须具有相同的类型。swap通常比从c2向c1拷贝元素快得多。赋值相关运算会导致指向左边容器内部的迭代器、引用和指针失效。而swap操作将容器内容交换不会导致指向容器的迭代器、引用和指针失效(容器类型为array和string的情况除外)。vector<string> svec1(10); vector<string> svec2(20); swap(svec1, svec2);执行完swap后svec1包含20个元素,svec2包含10个元素。容器本身并未交换,swap只是交换了两个容器的内部数据结构。除array外,swap不对任何元素进行拷贝、插入和删除操作,因此可以保证在常数时间内完成。假定迭代器iter在swap之前指向svec1[3],那么在swap之后它将指向svec2[3]。swap两个array会真正交换它们的元素,对于array,在swap操作之后,迭代器、引用和指针所绑定的元素保持不变,但元素值已经与另一个array中对应元素的值进行了交换。

4、assign操作用参数所指定的元素(的拷贝)替换左边容器中的所有元素。由于其旧元素被替换,因此传递给assign的迭代器不能指向调用assign的容器。

5、只有当其元素类型也定义了关系运算符时,我们才可以使用关系运算符来比较两个容器。容器的相等运算符实际上是使用元素的==运算符实现比较的,而其他关系运算符使用的是元素<运算符。

6、当我们用一个对象来初始化容器时,或将一个对象插入到容器中时,实际上放入到容器中的是对象值的一个拷贝,而不是对象本身。就像我们将一个对象传递给非引用参数一样,容器中的元素与提供值的元素之间没有任何关联。随后对容器中元素的任何改变都不会影响到原始对象,反之亦然。

7、如果我们传递给insert一对迭代器,它们不能指向添加元素的目标容器。接受元素个数或范围的insert版本返回指向第一个新加入的元素的迭代器。如果范围为空,不插入任何元素,insert操作会将第一个参数返回。

8、当调用push或insert成员函数时,我们将元素类型的对象传递给它们,这些对象被拷贝到容器中。而当我们调用一个emplace成员函数时,是将参数传递给元素类型的构造函数。emplace成员使用这些参数在容器管理的内存空间中直接构造元素。emplace函数的参数根据元素类型而变化,参数必须与元素类型的构造函数相匹配。

9、在容器中访问元素的成员函数(即front、back、下标和at)返回的都是引用。与往常一样,如果我们使用auto变量来保存这些函数的返回值,并且希望使用此变量来改变元素的值,必须记得将变量定义为引用类型。例如:auto &v1 = c.back();此时v1是c中最后一个元素的引用,但是auto v2 = c.back();此时v2不是引用,只是c中最后一个元素值的拷贝。下标运算符在编译时并不检查下标的是否越界,但是at会检查。

10、erase函数删除迭代器所指元素,返回被删除元素之后的迭代器。而pop函数和clear函数返回void。

11、如果在一个循环中插入/删除deque、vector或string中的元素,不要缓存end返回的迭代器,因为每次操作后end迭代器总是会失效的。

12、调用shrink_to_fit只是一个请求,标准库并不保证退还内存。

13、默认情况下,stack和queue是基于deque实现的,priority_queue是基于vector实现的。

14、stack只要求push_back、pop_back和back操作,因此可用除array和forw_list之外的任何容器类型来构造stack;queue要求back、push_back、front、push_front操作,因此queue可以构造于list或deque之上,而不能基于vector构造;priority_queue除了back、push_back、front操作之外还要求随机访问,因此priority_queue可以构造于vector或者deque之上,但不能基于list构造。

15、对于适配器只能使用适配器的操作而不能使用其底层容器的操作。

posted @ 2022-12-16 17:27  许卡文迪  阅读(124)  评论(0编辑  收藏  举报