- array只允许被赋值为类型和大小一样的array容器,所有顺序容器实例化为自定义类型时,若没有给自定义类型元素一个一个的赋值的话,则自定义类型必须有默认构造函数。
- 容器中的max_size代表容器能够装载最大元素的值,不同元素的容器的max_size可能不一样,一般至少有1e9的数据量。
- 每个容器类型都支持关系运算符,关系运算符比较规则与字符串比较规则一致,如果两个容器具有相同大小且所有元素都两两对应则两个容器相等。如果两个容器中较小的容器是较大的容器的前缀,则较小的容器小于较大的容器,如果两个容器中的某个位置对应的前面元素相同,但是该位置元素较大的容器大。如果容器使用的是自定义类型,则需要在类里面重载相关关系运算符,才能调用关系运算符。
#include <iostream> #include <fstream> #include <array> #include <vector> int main() { std::vector<int> v1 = { 1,3,5,7,9,12 }; std::vector<int> v2 = { 1,3,5,7,9,12 }; std::vector<int> v3 = { 1,3 }; std::cout << (v1 == v2) << " " << (v1 != v2) << " " << (v1 > v2) << " " << (v1 >= v2) << " " << (v1 <= v2) << " " << (v1 < v2) << " " << std::endl; }
1 0 0 1 1 0
- 向顺序容器添加元素的操作
在一个vector或者string尾部之外的任何位置,或是一个deque添加元素可能引起整个对象储存空间的重新分配。重新分配一个对象的储存空间需要分配新的内存,并将元素从旧的空间移动到新的空间中。
5. emplace相对于push或者insert可以直接使用传入的参数通过构造函数构造元素
#include <iostream>
#include <fstream>
#include <array>
#include <vector>
#include <string>
class Point
{
public:
int x, y, z;
std::string str;
explicit Point() = default; //如果没有默认构造函数,第17行会出问题
explicit Point(int a, int b, int c) :x(a), y(b), z(c) {};
explicit Point(std::string s) :str(s) {};
};
int main()
{
std::vector<Point> vec1(10);
std::vector<Point> vec2;
vec2.emplace_back();
vec2.emplace_back(1, 2, 3);
vec2.emplace_back("wer");
vec2.emplace_back(Point(1, 2, 3));
//调用拷贝构造函数
//vec2.push_back();
//vec2.push_back(1, 2, 3);
//vec2.push_back("wer");
//push_back不能像emplace_back直接把参数传递给构造函数创建对象,只能使用现成的对象
return 0;
}
- 使用at相比于使用索引器跟安全,如果数组越界at函数会抛出out_of_range异常,而索引器直接运行时错误。
#include <iostream> #include <fstream>#include <array> #include <vector> #include <string> #include <exception> int main() { std::vector<int> vec; try { //std::cout << vec[0]; 不会抛出异常,而是导致程序终止 std::cout << vec.at(0); } catch(std::exception exce) { std::cout << exce.what() << std::endl; } return 0; }
- 顺序容器的删除操作
上图中c.erase(b,e);中b指向要删除的第一个元素,e指向要删除的最后一个元素之后的位置,如果b==e,则不删除元素。
8. forward_list中插入或者删除操作
-
添加元素后不同的容器迭代器失效为:
-
为避免更改数据后迭代器失效问题,程序中每一个循环步骤中都更新迭代器,引用或者指针,如果循环中调用了insert或者erase,则可以将insert或者erase返回值更新被删除的迭代器。更改容器数据频繁的话,尽量不要保存end返回的迭代器,而是直接调用end返回的迭代器。
#include <iostream> #include <fstream> #include <array> #include <vector> #include <string> #include <exception> int main() { std::vector<int> vec = { 2,3,4,5,6 }; auto iter = vec.begin(); while (iter != vec.end()) { if (*iter & 1) { iter = vec.insert(iter, *iter); iter += 2; } else { iter = vec.erase(iter); } } return 0; }
-
空间分配接口:
-
子字符串操作
-
修改string的操作
- string搜索操作
-
string的compare的几种参数形式
-
string和数值之间的转换
-
所有容器适配器都支持的操作和类型
-
容器,迭代器和函数都有适配器。一个容器适配器接受一种已有的容器类型,使其行为看起来像一个不同的类型。默认情况下stack和queue是基于deque实现的,priority_queue是在vector之上实现的。对于给定的适配器,可以使用哪些容器是有限制的。所有适配器都要求容器具有添加和删除元素能力,因此适配器不能构造在array之上,当然由于forward_list没有接口直接访问尾元素,该容器同样不能使用。stack可以使用除了array和forward_list之外的任何容器类型构造。queue可以构造于list和deque之上,但不能基于vector构造,priority_queue可以构造于vector或者deque之上,但不能基于list构造。
#include <iostream> #include <fstream> #include <array> #include <vector> #include <string> #include <exception> #include <stack> #include <deque> int main() { std::deque<int> d{ 1, 2, 3, 4, 5, 6 }; std::vector<std::string> v{ "wer","Sdf","sdf" }; std::stack<int> stk(d); //上面的stack是基于deque实现的 std::stack<std::string, std::vector<std::string>> str_stk(v); //上面的stack不再是基于deque构造,而是基于vector构造 return 0; }
-
栈适配器拥有的操作。
-
队列适配器拥有的操作。