STL(C++)

https://gitee.com/quicksands/stl-source-code-analysis

C++11关键字:auto和decltype

  • auto:占位符类型说明符
    • 对于变量,auto x = expr; 从初始化器推导类型
  • decltype说明符
    • decltype (expr)声明从表达式得到的类型

容器

  • 容器是储存其他对象的对象。简单来说,每个容器提供了一种适配大部分类型的数据结构。
  • 容器分为四种:
    • 序列式容器:<array> <deque> <forward_list> <list> <vector>
    • 关联式容器:<map> <set>
    • 无序关联式容器:<unordered_map> <unordered_set>
    • 容器适配器:<queue> <stack>

序列式容器

顺序容器顺序容器实现能按顺序访问的数据结构
array(c++11)静态(固定长度) 的连续数组 (类模板)在这里插入图片描述
vector动态的连续数组 (类模板)Implementation
deque双端队列 (类模板)Implementation
forard_list(c++11)单链表 (类模板)
list双链表 (类模板)Implementation

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

eg
  • vector
    • vector<T>动态连续数组。
      • 动态指它的长度是可变的;连续指它的元素可用T*访问。
    • 它实现了两种元素访问
      • operator [],注意:不检查下标是否越界
      • 访问元素函数(返回元素的左值):front,at(int),back。其中,at检查下标越界,越界则抛出异常。
    • 实现了列表初始化(直接列表和复制列表)
  • 使用迭代器
    • 迭代器(Iterator)是用于遍历容器元素指针对象的包装。
    • 单向迭代器实现了以下运算符重载
      • operator ++,==, != , * 等,例如:++ 表示取容器中的下一个元素
    • 容器会提供一个或多个迭代器实现。
      • 例如:
        • vector提供正向和反向的迭代器。
        • 通过成员函数begin(),end()返回正向迭代器对象实例。
        • 通过成员函数rbegin(),rend()返回反向迭代器对象实例。
          在这里插入图片描述
          在这里插入图片描述

关联式容器

在这里插入图片描述

类名说明所在头文件
map通过键进行元素存取的关联数组<map>
multimap支持重复键的关联数组<map>
set任何元素的集合<set>
multiset可以重复的集合<set>
unordered_map无序的map,类似于哈希表<unordered_map>
unordered_set无序的set,类似于哈希表<unordered_set>
  • std::pair
    • std::map的某些函数使用了中的类std::pair,pair<T1, T2>代表一个由类型T1和类型T2组成的有序对。
    • 可以直接用构造函数std::pair<T1, T2> (v1, v2)进行构造,也可以用make_pair进行构造:auto p = make_pair<v1,v2>;
    • 通过p.first访问第一个元素,通过p.second访问第二个元素
map

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

multimap

在这里插入图片描述
在这里插入图片描述

set

在这里插入图片描述

适配器

在这里插入图片描述
在这里插入图片描述

stack

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

queue

在这里插入图片描述

priority_queue

在这里插入图片描述

迭代器

  • 迭代器是每种容器各自定义的一个或多个不同于容器的类,比如vector<T>::iterator,它主要用于访问、修改、增加、删除容器中的元素。
  • 按照功能的不同,C++17之前的迭代器分为:
    • LegacyInputIterator(输入迭代器)
    • LegacyOutputIterator(输出迭代器)
    • LegacyForwardIterator(单向迭代器)
    • LegacyBidirectionalIterator(双向迭代器)
    • LegacyRandomAccessIterator(随机迭代器)
  • C++17加入了LegacyContiguousIterator(连续迭代器)
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 失效案例分析
vector<int> ivv1 {1,2,4,5,3};
for (auto it = ivv1.begin(); it != ivv1.end(); it++) {
    if (*it == 3) ivv1.erase(it);  
}
  • 在 for 循环中,当你调用 ivv1.erase(it) 删除元素 3 后,当前迭代器 it 就失效了(即不再指向合法位置);

  • 但是 for 循环的条件中仍然执行了 it++,这导致你对一个已经失效的迭代器自增,这属于未定义行为(UB);

  • 结果可能是程序崩溃、输出错误结果,或“看起来没错但风险极高”。

修正代码

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> ivv1 {1,2,3,4,5};
    for (auto it = ivv1.begin(); it != ivv1.end(); ) {
        if (*it == 3)
            it = ivv1.erase(it); // 返回新的有效迭代器
        else
            ++it;
    }
    for (auto x : ivv1) cout << x << ",";
    cout << endl;
}

算法

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#include<iostream>
#include<functional>
using namespace std;
int twox_add_threey(int x,int y){
	return 2*x+3*y;
}

class Foos{
public:
	static int twox_add_threey(int x,int y){
		return 2*x+3*y;
	}
};

class Food{
public:
	int twox_add_threey(int x,int y){
		return 2*x+3*y;
	}
};

class Func{
private:
	int a,b;
public:
	Func(int _a=0,int _b=0):a(_a),b(_b){}
	int operator()(int x,int y){
		return a*x+b*y;
	}
};

void callback_client(std::function<int(int,int)> f,int a,int b){
	cout<<f(a,b)<<endl;
}
int main(){
	cout<<"普通函数回调:";
	callback_client(twox_add_threey,1,2);
	
	cout<<"类的静态成员函数回调:";
	callback_client(Foos::twox_add_threey,1,2); 
	
	cout<<"类的动态成员函数回调:";//动态成员函数需要对象才能调用
	Food food;
	callback_client(std::bind(&Food::twox_add_threey,&food,std::placeholders::_1,std::placeholders::_2),1,2);
	callback_client(std::bind(food.twox_add_threey,&food,std::placeholders::_1,std::placeholders::_2),1,2);
	callback_client([&food](int x,int y){return food.twox_add_threey(x,y);},1,2); 
	
	cout<<"函数对象回调:";callback_client(Func(2,3),1,2); 
	cout<<"匿名函数回调:";callback_client([](int x,int y){return 2*x+3*y;},1,2);
	return 0;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值