• C++标准模板库——vector的使用及其模拟实现


    目录

    一. vector的介绍
    1.vector的介绍

    二.vector的使用

    1. vector中常见接口的介绍
    2. vector的构造和析构函数
    3. vector的三种遍历方式

    三.vector的模拟实现

    1. vector的增删查改
    2. vector容器的容量变化和大小增减
    3. vector迭代器失效问题
    4. vector的小框架 构造函数和析构函数
    5. 迭代器和operator[]的实现
    6. vector的拷贝构造函数和operator=
    7. memcpy拷贝问题
    8. 模拟实现整体源代码

    一.vector的介绍

    1.vector的介绍

    更多详细细节可以参考 vector参考书
    在这里插入图片描述

    1. vector是表示可变大小数组的序列容器。
    2. 就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自动处理。
    3. 本质讲,vector使用动态分配数组来存储它的元素。当新元素插入时候,这个数组需要被重新分配大小
      为了增加存储空间。其做法是,分配一个新的数组,然后将全部元素移到这个数组。就时间而言,这是一个相对代价高的任务,因为每当一个新的元素加入到容器的时候,vector并不会每次都重新分配大小。
    4. vector分配空间策略:vector会分配一些额外的空间以适应可能的增长,因为存储空间比实际需要的存储空间更大。不同的库采用不同的策略权衡空间的使用和重新分配。但是无论如何,重新分配都应该是对数增长的间隔大小,以至于在末尾插入一个元素的时候是在常数时间的复杂度完成的。
    5. 因此,vector占用了更多的存储空间,为了获得管理存储空间的能力,并且以一种有效的方式动态增长。
    6. 与其它动态序列容器相比(deque, list and forward_list), vector在访问元素的时候更加高效,在末尾添加和删除元素相对高效。对于其它不在末尾的删除和插入操作,效率更低。比起list和forward_list统一的迭代器和引用更好。

    二. vector的使用

    1. vector的常见接口介绍

    1.1vector的定义

    在这里插入图片描述

    1.2 vector 迭代器 的使用

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

    1.3 vector的空间增长问题

    在这里插入图片描述
    测试代码:

    #include
    #include
    using namespace std;
    
    void Test_vector2()
    {
    	size_t sz;
    	vector<int> v;
    	sz = v.capacity();
    	cout << "making v grow:\n";
    	for (int i = 0; i < 100; ++i)
    	{
    		v.push_back(i);
    		if (sz != v.capacity())
    		{
    			sz = v.capacity();
    			cout << "capacity changed: " << sz << '\n';
    		}
    	}
    }
    
    int main()
    {
    	Test_vector2();
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    运行结果:
    在这里插入图片描述

    vs:运行结果:vs下使用的STL基本是按照1.5倍方式扩容

    通过reserve()接口提前设置好容量,我们可以减少扩容次数,减少扩容对效率的损耗

    测试代码:

    #include
    #include
    using namespace std;
    
    void Test_vector1()
    {
    	vector<int> v;
    	for (size_t i = 0; i < 10; i++)
    	{
    		v.push_back(i);
    	}
    
    
    }
    
    void Test_vector2()
    {
    	size_t sz;
    	vector<int> v;
    	sz = v.capacity();
    	cout << "making v grow:\n";
    	for (int i = 0; i < 100; ++i)
    	{
    		v.push_back(i);
    		if (sz != v.capacity())
    		{
    			sz = v.capacity();
    			cout << "capacity changed: " << sz << '\n';
    		}
    	}
    }
    
    void Test_vector3()
    {
    	vector<int> v;
    	size_t sz = v.capacity();
    	v.reserve(100); // 提前将容量设置好,可以避免一遍插入一遍扩容
    	cout << "making bar grow:\n";
    	for (int i = 0; i < 100; ++i)
    	{
    		v.push_back(i);
    		if (sz != v.capacity())
    		{
    			sz = v.capacity();
    			cout << "capacity changed: " << sz << '\n';
    		}
    	}
    }
    
    int main()
    {
    	Test_vector3();
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    在这里插入图片描述

    1.4vector的增删查改

    在这里插入图片描述
    测试代码:

    void Test_vector1()
    {
    	vector<int> v;
    	for (size_t i = 0; i < 10; i++)
    	{
    		v.push_back(i);
    	}
    
    	cout << "尾插数据后:" << endl;
    	for (size_t i = 0; i < v.size(); i++)
    	{
    		cout << v[i] << " ";//像数组一样用[]访问vector中的元素
    	}
    	cout << endl;
    
    	v.pop_back();
    	v.pop_back();
    	cout << "尾删两个数据后:" << endl;
    
    	for (size_t i = 0; i < v.size(); i++)
    	{
    		cout << v[i] << " ";
    	}
    	cout << endl;
    
    	vector<int>::iterator it = v.begin();
    	v.insert(it+3, 30);//在下标为3的前面插入一个30
    	for (size_t i = 0; i < v.size(); i++)
    	{
    		cout << v[i] << " ";
    	}
    	cout << endl;
    
    	it = v.erase(it+3);//删除it位置的数,并把该位置被删除的后面的数的迭代器返回给it
    	for (size_t i = 0; i < v.size(); i++)
    	{
    		cout << v[i] << " ";
    	}
    	cout << endl;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    运行结果:
    在这里插入图片描述

    2.vector的构造函数和析构函数

    在这里插入图片描述

    在这里插入图片描述

    3.vector的三种遍历方式

    测试代码:

    void Test_vector4()
    {
    	vector<int> v;
    	for (size_t i = 0; i < 10; i++)
    	{
    		v.push_back(i);
    	}
    
    	cout << "第一种用[]进行遍历:" << endl;
    	for (size_t i = 0; i < v.size(); i++)
    	{
    		cout << v[i] << " ";
    	}
    
    	cout << endl;
    
    	cout << "第二种用迭代器进行遍历:" << endl;
    
    	vector<int>::iterator it = v.begin();
    	while (it != v.end())
    	{
    		cout << *it << " ";
    		it++;
    	}
    	cout << endl;
    
    	cout << "第三种用范围for进行遍历:" << endl;
    	for (auto e : v)
    	{
    		cout << e << " ";
    	}
    	cout << endl;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    运行结果:
    在这里插入图片描述

    三.vector的模拟实现

    开始时定义个自己的命名空间,然后利用类模板控制vector可以存放多种类型的数据,定义迭代器和私有成员变量,_start相当于vector常用接口中的begin(),_finish相当于end(),_endofstorage相当于_start+capacity();
    在这里插入图片描述

    #pragma once
    
    #include
    #include
    #include
    using namespace std;
    namespace  simulation
    {
    	template<class T>
    	class vector
    	{
    
    	public:
    		typedef T* iterator;
    		typedef const T* const_iterator;
    
    
    
    	private:
    		iterator _start;
    		iterator _finish;
    		iterator _endofstorage;
    	};
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    1. vector的增删查改

    代码:

    //尾插
    void  push_back(const T& x)
    {
    
    	if (_finish == _endofstorage)
    	{
    		reserve(capacity() == 0 ? 4 : capacity() * 2);			
    	}
    
    	*_finish = x;
    	_finish++;
    }
    
    //在pos位置前插入x
    void insert(iterator pos, const T& x)
    {
    	assert(pos >= _start);
    	assert(pos <= _finish);
    	if (_finish == _endofstorage)
    	{
    		size_t len = pos - _start;
    		reserve(capacity() == 0 ? 4 : capacity() * 2);
    		pos = _start + len;
    
    	}
    
    	iterator end = _finish - 1;
    	while (end >= pos)
    	{
    		*(end + 1) = *end;
    		end--;
    	}
    
    	*pos = x;
    	_finish++;
    
    }
    
    //删除pos位置的元素
    iterator erase(iterator pos)
    {
    	assert(pos >= _start);
    	assert(pos <= _finish);
    
    	iterator it = pos+1;
    	while (it<_finish)
    	{
    		 *(it-1) = *it;
    		++it;
    	}
    
    	_finish--;
    
    	return pos;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    测试代码:

    void test_vector2()
    {
    	simulation::vector<int> v;
    	//尾插
    	v.push_back(1);
    	v.push_back(2);
    	v.push_back(3);
    	v.push_back(4);
    	v.push_back(5);
    	v.push_back(6);
    	v.push_back(7);
    	v.push_back(8);
    
    	for (int e : v)
    	{
    		cout << e << " ";
    	}
    	cout << endl;
    	
    	//在4前面插入一个40
    	v.insert(v.begin() + 3, 40);
    	for (int e : v)
    	{
    		cout << e << " ";
    	}
    	cout << endl;
    	
    	//头插一个100
    	v.insert(v.begin(), 100);
    	for (int e : v)
    	{
    		cout << e << " ";
    	}
    	cout << endl;
    	
    	//尾插1000
    	v.insert(v.end(), 1000);
    	for (int e : v)
    	{
    		cout << e << " ";
    	}
    	cout << endl;
    	
    	//头删
    	v.erase(v.begin());
    	for (int e : v)
    	{
    		cout << e << " ";
    	}
    	cout << endl;
    
    	//尾删
    	v.erase(v.end() - 1);
    	for (int e : v)
    	{
    		cout << e << " ";
    	}
    	cout << endl;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59

    运行结果:
    在这里插入图片描述

    1. vector容器的容量变化和大小增减

    成员函数实现:

    void reserve(size_t n)
    		{
    			if (n > capacity())
    			{
    				size_t sz = size();
    				T* tmp = new T[n];
    
    				if (_start)
    				{
    					//memcpy(tmp, _start, sizeof(T) * sz);
    					for (size_t i = 0; i < sz; i++)
    					{
    						tmp[i] = _start[i];
    					}
    
    					delete[] _start;
    				}
    				_start = tmp;
    				_finish = _start + sz;
    				_endofstorage = _start + n;
    			}
    		}
    
    		void resize(size_t n, const T& val = T())
    		{
    			if (n <= _finish)
    			{
    				_finish = _start + n;
    			}
    			else
    			{
    				reserve(n);
    				while (n + _start > _finish)
    				{
    					*_finish = val;
    					_finish++;
    				}
    			}
    		}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    在这里插入图片描述

    1. vector迭代器失效问题
      在这里插入图片描述
      在pos位置插入数据时,可能存在扩容问题,扩容一般情况下都会找一块新的空间,然后释放旧空间,把指针指向新的空间,但是此时传进去的参数pos没有跟着空间的变化而与_start发生相对变化,所以这时迭代器就失效了,不能再让迭代器往后使用了,此时想要不让迭代器失效只能保留pos与_start的偏移量,然后等到扩容后把pos位置的迭代器更新,那么pos位置的迭代器才能继续使用。

    在这里插入图片描述
    erase这个接口也会使得迭代器失效,原因在于删除pos位置的数据之后,pos指向的数据的值已经被删除,所以想要继续使用迭代器需要在该接口返回值那里返回一个迭代器,指向被删除的值的下一个位置的迭代器,方能继续使用.

    所以这样实现才是合理的

    //删除pos位置的元素
    iterator erase(iterator pos)
    {
    	assert(pos >= _start);
    	assert(pos <= _finish);
    
    	iterator it = pos+1;
    	while (it<_finish)
    	{
    		 *(it-1) = *it;
    		++it;
    	}
    
    	_finish--;
    
    	return pos;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    1. vector的小框架 构造函数和析构函数
      代码实现:
    template <class InputIterator>
    vector(InputIterator first, InputIterator last)
    {
    	while (first != last)
    	{
    		push_back(*first);
    		first++;
    	}
    }
    
    vector(size_t n, const T& val = T())
    {
    	reserve(n);
    	for (size_t i = 0; i < n; i++)
    	{
    		push_back(val);
    	}
    }
    
    vector(int n, const T& val = T())
    {
    	reserve(n);
    	for (int i = 0; i < n; i++)
    	{
    		push_back(val);
    	}
    }
    
    
    vector()
    	:_start(nullptr)
    	,_finish(nullptr)
    	,_endofstorage(nullptr)
    {
    
    }
    
    vector(const vector<T>& v)
    	:_start(nullptr)
    	, _finish(nullptr)
    	, _endofstorage(nullptr)
    {
    	reserve(v.capacity());
    	for (auto& e : v)
    	{
    		push_back(e);
    	}
    }
    
    vector<T>& operator=(vector<T> tmp)
    {
    	swap(tmp);
    	return *this;
    }
    
    void swap(vector<T>& v)
    {
    	std::swap(_start, v._start);
    	std::swap(_finish, v._finish);
    	std::swap(_endofstorage, v._endofstorage);
    }
    
    ~vector()
    {
    	delete[] _start;
    	_start = _finish = _endofstorage = nullptr;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    1. 迭代器和operator[]的实现
    public:
    		typedef T* iterator;
    		typedef const T* const_iterator;
    
    		iterator begin()
    		{
    			return _start;
    		}
    
    		iterator end()
    		{
    			return _finish;
    		}
    
    		const_iterator begin() const
    		{
    			return _start;
    		}
    
    		const_iterator end() const
    		{
    			return _finish;
    		}
    		T& operator[](size_t pos)
    		{
    			assert(pos < size());
    			return _start[pos];
    		}
    
    		T& operator[](size_t pos) const
    		{
    			assert(pos < size());
    			return _start[pos];
    		}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    1. vector的拷贝构造函数和operator=
    vector(const vector<T>& v)
    			:_start(nullptr)
    			, _finish(nullptr)
    			, _endofstorage(nullptr)
    {
    	reserve(v.capacity());
    	for (auto& e : v)
    	{
    		push_back(e);
    	}
    }
    
    vector<T>& operator=(vector<T> tmp)
    {
    	swap(tmp);
    	return *this;
    }
    
    void swap(vector<T>& v)
    {
    	std::swap(_start, v._start);
    	std::swap(_finish, v._finish);
    	std::swap(_endofstorage, v._endofstorage);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    1. memcpy拷贝问题
      memcpy进行拷贝时会对自定义数据类型的数据进行浅拷贝,而浅拷贝在进行析构的时候,会进行两次析构,导致出现错误,所以拷贝的时候应该进行深拷贝
      如下是代码实现
    void reserve(size_t n)
    		{
    			if (n > capacity())
    			{
    				size_t sz = size();
    				T* tmp = new T[n];
    
    				if (_start)
    				{
    					//memcpy(tmp, _start, sizeof(T) * sz);
    					for (size_t i = 0; i < sz; i++)
    					{
    						tmp[i] = _start[i];
    					}
    
    					delete[] _start;
    				}
    				_start = tmp;
    				_finish = _start + sz;
    				_endofstorage = _start + n;
    			}
    		}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    通过for循环一份一份的拷贝到新的空间就不会造成空间被释放两次

    1. 模拟实现整体源代码
    #pragma once
    
    #include
    #include
    #include
    using namespace std;
    namespace  simulation
    {
    	template<class T>
    	class vector
    	{
    
    	public:
    		typedef T* iterator;
    		typedef const T* const_iterator;
    
    		iterator begin()
    		{
    			return _start;
    		}
    
    		iterator end()
    		{
    			return _finish;
    		}
    
    		const_iterator begin() const
    		{
    			return _start;
    		}
    
    		const_iterator end() const
    		{
    			return _finish;
    		}
    
    		size_t size() const
    		{
    			return _finish - _start;
    		}
    
    		size_t capacity() const
    		{
    			return _endofstorage - _start;
    		}
    
    		template <class InputIterator>
    		vector(InputIterator first, InputIterator last)
    		{
    			while (first != last)
    			{
    				push_back(*first);
    				first++;
    			}
    		}
    
    		vector(size_t n, const T& val = T())
    		{
    			reserve(n);
    			for (size_t i = 0; i < n; i++)
    			{
    				push_back(val);
    			}
    		}
    
    		vector(int n, const T& val = T())
    		{
    			reserve(n);
    			for (int i = 0; i < n; i++)
    			{
    				push_back(val);
    			}
    		}
    
    
    		vector()
    			:_start(nullptr)
    			, _finish(nullptr)
    			, _endofstorage(nullptr)
    		{
    
    		}
    
    		vector(const vector<T>& v)
    			:_start(nullptr)
    			, _finish(nullptr)
    			, _endofstorage(nullptr)
    		{
    			reserve(v.capacity());
    			for (auto& e : v)
    			{
    				push_back(e);
    			}
    		}
    
    		vector<T>& operator=(vector<T> tmp)
    		{
    			swap(tmp);
    			return *this;
    		}
    
    		void swap(vector<T>& v)
    		{
    			std::swap(_start, v._start);
    			std::swap(_finish, v._finish);
    			std::swap(_endofstorage, v._endofstorage);
    		}
    
    		~vector()
    		{
    			delete[] _start;
    			_start = _finish = _endofstorage = nullptr;
    		}
    
    
    
    		T& operator[](size_t pos)
    		{
    			assert(pos < size());
    			return _start[pos];
    		}
    
    		T& operator[](size_t pos) const
    		{
    			assert(pos < size());
    			return _start[pos];
    		}
    
    		void reserve(size_t n)
    		{
    			if (n > capacity())
    			{
    				size_t sz = size();
    				T* tmp = new T[n];
    
    				if (_start)
    				{
    					//memcpy(tmp, _start, sizeof(T) * sz);
    					for (size_t i = 0; i < sz; i++)
    					{
    						tmp[i] = _start[i];
    					}
    
    					delete[] _start;
    				}
    				_start = tmp;
    				_finish = _start + sz;
    				_endofstorage = _start + n;
    			}
    		}
    
    		void resize(size_t n, const T& val = T())
    		{
    			if (n <= _finish)
    			{
    				_finish = _start + n;
    			}
    			else
    			{
    				reserve(n);
    				while (n + _start > _finish)
    				{
    					*_finish = val;
    					_finish++;
    				}
    			}
    		}
    
    
    		void  push_back(const T& x)
    		{
    
    			if (_finish == _endofstorage)
    			{
    				reserve(capacity() == 0 ? 4 : capacity() * 2);
    			}
    
    			*_finish = x;
    			_finish++;
    		}
    
    		void insert(iterator pos, const T& x)
    		{
    			assert(pos >= _start);
    			assert(pos <= _finish);
    			if (_finish == _endofstorage)
    			{
    				size_t len = pos - _start;
    				reserve(capacity() == 0 ? 4 : capacity() * 2);
    				pos = _start + len;
    
    			}
    
    			iterator end = _finish - 1;
    			while (end >= pos)
    			{
    				*(end + 1) = *end;
    				end--;
    			}
    
    			*pos = x;
    			_finish++;
    
    		}
    
    		iterator erase(iterator pos)
    		{
    			assert(pos >= _start);
    			assert(pos <= _finish);
    
    			iterator it = pos + 1;
    			while (it < _finish)
    			{
    				*(it - 1) = *it;
    				++it;
    			}
    
    			_finish--;
    
    			return pos;
    		}
    
    
    	private:
    		iterator _start;
    		iterator _finish;
    		iterator _endofstorage;
    	};
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
  • 相关阅读:
    前后端接口设计与配置中心系统<二十九>-------HiAbility SDK开发4【支付能力集成】
    Java 把多个音频拼接成一个
    【PyTorch】深度学习实践之 逻辑斯蒂回归 Logistic Regression
    凭什么Java程序员的工资那么高,原来要“啃透”这999页阿里P7学习笔记
    IDEA创建父子项目
    Spring DI 简单案例
    计算机组成与体系结构入门(二)
    WPF不弹出控件的情况下,将控件内容生成截图
    [极致用户体验] 微信设置大字号后,iOS加载网页时闪动怎么办?
    【MySQL】A01、性能优化-参数监控&分析
  • 原文地址:https://blog.csdn.net/weixin_63181097/article/details/133167967