四、模板与容器
1. 模板
1.1 函数模板
#include <iostream>
using namespace std;
// 函数模板声明
template<typename T> // 也可使用 class
T add(T a, T b) {
return a + b;
}
int main() {
string a = "hello";
string b = "world";
cout << add(a, b) << endl; // 输出 hello world
cout << add(1, 2) << endl; // 输出 3
cout << add(1.3, 2.2) << endl;// 输出 3.5
return 0;
}
1.2 类模板(类内声明类外定义)
#include <iostream>
using namespace std;
// 类模板声明
template<class T>
class Test {
private:
T val;
public:
Test(T val); // 构造函数声明
T get_val(); // 获取值声明
void set_val(const T &val); // 设置值声明
};
// 类模板成员函数定义
template<class T>
Test<T>::Test(T val) : val(val) {}
template<class T>
T Test<T>::get_val() {
return val;
}
template<class T>
void Test<T>::set_val(const T &val) {
this->val = val;
}
int main() {
Test<int> t1(20);
cout << t1.get_val() << endl;
t1.set_val(10);
cout << t1.get_val() << endl;
Test<double> t2(20.3);
cout << t2.get_val() << endl;
return 0;
}
2. 容器
2.1 标准模板库(STL)
STL包含三大组件:
- 算法(algorithm)
- 容器(container)
- 迭代器(iterator)
2.2 顺序容器
2.2.1 array数组
#include <array>
#include <iostream>
using namespace std;
int main() {
array<int, 5> arr = {1, 2, 3}; // 后两位自动初始化为0
// 访问元素
cout << arr[0] << endl; // 1
cout << arr.at(4) << endl; // 0(推荐使用at())
// 修改元素
arr[3] = 200;
// 遍历方式
for(int i = 0; i < arr.size(); i++) {
cout << arr[i] << endl;
}
for(auto num : arr) {
cout << num << endl;
}
return 0;
}
2.2.2 vector向量
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> vec(5); // 创建长度为5的int容器
// 添加元素
vec.push_back(222);
vec.insert(vec.begin()+2, 333);
// 修改元素
vec[1] = 666;
vec.at(3) = 777;
// 删除元素
vec.pop_back(); // 删除末尾
vec.erase(vec.begin()+1);// 删除指定位置
// 遍历方式
for(int i = 0; i < vec.size(); i++) {
cout << vec[i] << endl;
}
for(auto num : vec) {
cout << num << " ";
}
return 0;
}
2.2.3 list列表
#include <list>
#include <string>
#include <iostream>
using namespace std;
int main() {
list<string> lis(5, "hello"); // 初始化5个"hello"
// 添加元素
lis.push_back("world");
lis.push_front("haha");
lis.insert(++lis.begin(), "222");
// 删除元素
lis.pop_front();
auto it = lis.begin();
advance(it, 1);
lis.insert(it, "333");
lis.erase(--lis.end());
// 修改元素
it = lis.end();
advance(it, 2);
*it = "200";
// 遍历输出
for(string s : lis) {
cout<< s << endl;
}
return 0;
}
2.2.4 deque队列
#include <deque>
#include <iostream>
using namespace std;
int main() {
deque<int> deq(5);
// 添加元素
deq.push_back(222);
deq.insert(deq.begin()+2, 333);
// 修改元素
deq[1] = 666;
deq.at(3) = 777;
// 删除元素
deq.pop_back();
deq.erase(deq.begin()+1);
// 遍历输出
for(int i = 0; i < deq.size(); i++) {
cout << deq[i] << endl;
}
return 0;
}
2.3 关联容器
2.3.1 map键值对
#include <map>
#include <string>
#include <iostream>
using namespace std;
int main() {
map<string, int> ma;
// 添加元素
ma["身高"] = 180;
ma.insert(make_pair("年龄", 24));
// 修改元素
ma["身高"] = 175;
// 查找元素
if(ma.find("体重") == ma.end()) {
cout << "没有体重数据" << endl;
}
// 删除元素
ma.erase("年龄");
// 遍历输出
for(auto& pair : ma) {
cout << pair.first << ": " << pair.second << endl;
}
return 0;
}
2.4 迭代器遍历
#include <vector>
#include <array>
#include <list>
#include <deque>
#include <map>
#include <iostream>
using namespace std;
int main() {
// 遍历string
string s = "abcdefg";
for(auto it = s.cbegin(); it != s.cend(); ++it) {
cout << *it << " ";
}
cout << endl;
// 遍历array
array<int, 5> arr = {1, 2, 3, 4, 5};
for(auto it = arr.cbegin(); it != arr.cend(); ++it) {
cout << *it << " ";
}
cout << endl;
// 遍历map
map<string, int> ma = {{"A", 1}, {"B", 2}};
for(auto it = ma.cbegin(); it != ma.cend(); ++it) {
cout << it->first << ":" << it->second << endl;
}
return 0;
}