#include<iostream>
#include<vector>
#include<deque>
#include<list>
#include<forward_list>
#include<array>
#include<string>
#include<stack>
using namespace std;
//可以随机访问的有:vector,deque,array,string
//list, forward_list 不支持快速随机访问,但是删除和插入元素很快,deque在两端添加和删除元素的速度都是很快的
class noDefalut {
public:
int get(int a) {
return a;
}
private:
int a;
int b;
};
void test() {
//假定noDefault是一个没有默认构造函数的类型
vector<noDefalut>v1(10, init);
vector<noDefalut>v2(10); //错误,必须提供一个元素初始化器
//容器类型成员
list<string>::iterator iter;
vector<int>::difference_type count;
//begin 和end成员
list<string> a = { "Milton", "Shakespeare", "Austen" };
auto it1 = a.begin();
auto it2 = a.rbegin();
auto it3 = a.cbegin();
auto it4 = a.crbegin();
//当我们将一个容器初始化为另一个容器的拷贝时,我们要保证两个容器的类型和元素类型匹配
//标准库array具有固定的大小
array<int, 42>;
array<string, 10>;
array<int, 10>::size_type i;
//array<int>::size_type j; 错误,array<int>不是一个类型
array<int, 10>ia1;
array<int, 10> ia2 = { 42 }; // 第一个元素为42,其他元素为0
// 我们不可以对内置数组进行拷贝和对象赋值操作,但是可以对array进行
int digs[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
//int cpy[10] = digs; 错误内置数组不支持拷贝操作
array<int, 10>digits = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
array<int, 10>copy = digits;
//使用assign(仅顺序容器)
list<string> names;
vector<const char*> oldstyle;
//names = oldstyle; 错误容器类型不匹配
names.assign(oldstyle.cbegin(), oldstyle.cend());
list<string>slist1(1);
slist1.assign(10, "Hiya");
//使用swap
vector<string>svec1(10);
vector<string>svec2(24);
swap(svec1, svec2);
//与其他容器不同,对一个string调用swap会导致迭代器,引用和指针失效,与其他容器不同,swap两个array会真正交换他们的元素
//push_back
//除array和forward_list之外,每个顺序容器都支持push_back
//list,forward_list,deque容器还支持名为push_front的类似操作
list<int>ilist;
for (size_t ix = 0; ix != 4; ix++) {
ilist.push_back(ix);
}
//如果我们给insert一对迭代器,他们不能指向添加元素的目标容器
//使用insert的返回值
list<string>lst;
auto iter = lst.begin();
string word;
while (cin >> word) {
iter = lst.insert(iter, word);
}
//使用emplace操作
/*
emplace_front,emplace_back,emplace ,这些操作构造而不是拷贝元素,这些操作分别对应于push_front,insert,push_back
当调用push或insert成员函数时,我们将元素类型的对象传递给他们,这些对象被拷贝到容器中,而我们调用emplace时,则是将参数传递给元素类型的构造函数
emplace函数在容器中直接构造函数,传递给emplace函数的参数必须与元素类型的构造函数相匹配
*/
//访问成员函数返回的是引用
vector<int>c;
if (!c.empty()) {
c.front() = 42;
auto& v = c.back();
v = 1024;
auto v2 = c.back(); //v2不是一个引用,它是c.back()的一个拷贝
v2 = 0; //没有改变c中的元素
}
//下标操作和安全的随机访问
vector<string>svec;
cout << svec[0]; //运行时报错
//cout >> svec.at[0]; 抛出一个out of range的异常
//从元素内部删除一个奇数
list<int>lst = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
auto it = lst.begin();
while (it != lst.end()) {
if (*it % 2) {
it = lst.erase(it);
}
else {
++it;
}
}
//删除多个元素
lst.clear();
lst.erase(lst.begin(), lst.end());
//从forward_list中删除元素
forward_list<int> flst = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
auto prev = flst.before_begin();
auto curr = flst.begin();
while (curr != flst.end()) {
if (*curr % 2) {
curr = flst.erase_after(prev);
}
else {
prev = curr;
++curr;
}
}
//改变容器大小
list<int> ilist(10, 42);
ilist.resize(15);
ilist.resize(25, -1);
ilist.resize(5);
//编写改变容器的循环程序
vector<int> vi = { 0, 1, 2, 3, 4 ,5 ,6, 7, 8, 9 };
auto iter = vi.begin();
while (iter != vi.end()) {
if (*iter % 2) {
iter = vi.insert(iter, *iter);
iter += 2;
}
else {
iter = vi.erase(iter);
}
}
//不要保存end返回的迭代器,必须在每次插入时重新调用end()
/*begin = v.begin();
while (begin != v.end()) {
++begin;
begin = v.insert(begin, 42);
++beign;
}*/
//字符串操作
//substr
string s("hello world");
string s2 = s.substr(0, 5);
s.insert(s.size(), 5, '!');
const char* cp = "stately pluump buck";
s.assign(cp, 7); //s="stately"
s.insert(s.size(), cp + 7); // s = stately plump buck
string s("c++ prime"), s2 = s;
s.insert(s.size(), "4th ed");
s2.append("4th ed");
s.erase(11, 3);
s.insert(11, "5th");
s2.replace(11, 2, "5th"); //从位置11开始删除两个字符,并插入5th
//vector 收缩内存
vector<int>s;
for (int i = 0; i < 10000; i++) {
s.push_back(i);
}
s.resize(3);
cout << s.size() << endl;
cout << s.capacity() << endl;
vector<int>(s).swap(s);//匿名对象
cout << s.capacity() << endl;
cout << s.size() << endl;
//vector预留空间
vector<int>p;
p.reserve(100000);
int num = 0;
int* q = NULL;
for (int i = 0; i < 10000; i++) {
p.push_back(i);
if (q != &p[0]) {
q = &p[0];
num++;
}
}
cout << num << endl;
//string搜索操作
string name("annabelle");
auto pos1 = name.find("anne");
string lowercase("annablele");
pos1 = lowercase.find("Ann"); //pos1 = npos
string numbers("0123456789");
string name("r2d2"); // 返回name中第一个数字的下标
auto pos = name.find_first_of(numbers);
string dept("03423");
auto pos = dept.find_first_not_of(numbers);
//逆向搜索
string river("mississippi");
auto first_pos = river.find("is");
auto last_pos = river.rfind("is");
//数值转换
int i = 42;
string s = to_string(i);
double = stod(s); //将字符串s转换为浮点数;
//还有很多翻阅书328
//容器适配器:一个容器适配器接受一种已有的容器类型,使其看起来像一张不同的类型
stack<int>intstack;
for (size_t ix = 0; ix != 10; ++ix) {
intstack.push(ix);
}
while (!intstack.empty()) {
int value = intstack.top();
}
}
int main() {
system("pause");
return 0;
}