深入浅出之STL源码分析8_三个指针
引言
在第一篇文章 深入浅出之STL源码分析1_vector基本操作-CSDN博客
中有引出了下面的几个问题
1.刚才我提到了我的编译器版本是g++ 11.4.0,而我们要讲解的是STL(标准模板库),那么二者之间的关系是什么?STL安装后我们到哪里去看源码?
2.我们引入了头文件#include<vector>
这里的vector的内容是什么?
3.vector<int> test_vector; 这中定义方式是干什么?<>的作用是什么?
4.test_vector.push_back(22); 对于stl源码底层到底做了什么?把对应的数据插入到了哪个地址了?
什么时候分配的虚拟内存?什么时候扩容?什么时候会分配物理内存?
下面开始讲解问题4.由于这个的内容将会把vector的所有源码都呈现出来,所以这个将会分不同的小节来进行讲解。
从push_back源码开始看起
#include<vector>
#include<iostream>
using namespace std;
int main(int argc,char *argv[]){vector<int> test_vector;test_vector.push_back(22);std::cout << test_vector.back() << std::endl;return 0;
}
向里继续看源码,
看到我们这里会调用push_back的这个函数:参数是个右值引用,所以接的是右值,而我们传进来的是22,确实是个右值。
#if __cplusplus >= 201103Lvoidpush_back(value_type&& __x){ emplace_back(std::move(__x)); }
我们再来继续追踪这个 emplace_back源码:
通过这个源码我们可以看到有几个重要的点
1.开头的这种写法是什么意思?
#if __cplusplus >= 201103L
template<typename _Tp, typename _Alloc>
template<typename... _Args>
为啥这个类成员函数的实现的时候,怎么有两个template<>,这个我们可以看下成员函数的声明,就很清楚了,
#if __cplusplus >= 201103Lvoidpush_back(value_type&& __x){ emplace_back(std::move(__x)); }template<typename... _Args>
#if __cplusplus > 201402Lreference
#elsevoid
#endifemplace_back(_Args&&... __args);
#endif
也就是类成员函数声明的时候,每个成员函数又可以有自己的模版参数,比方这里当
#if __cplusplus >= 201103L的时候,
template<typename... _Args>
类成员函数有了自己的模版参数,所以才有了上面函数在实现的时候,带了两个template<>,一个是整个类的,一个是类成员函数自己的。
这里我们可以写一个简单的小demo来看下。
2.this->_M_impl._M_finish != this->_M_impl._M_end_of_storage 这个又是什么东西?