C++中的反向迭代器

C++中的反向迭代器

为啥反向迭代器的讲解要单独拎出来讲,没有在讲各个容器的时候顺手讲了呢? 主要是因为c++中的反向迭代器和正向迭代器的实现不太一样。

它思想不复杂,主要是巧。

在这里插入图片描述

来,我们按照我们刚刚的想法把代码写出来

#pragma once
#include<cassert>namespace lx
{template <class T>struct ListNode{ListNode<T>* next;ListNode<T>* prev;T data;ListNode(const T& x=T()):next(nullptr),prev(nullptr),data(x){}};template <class T, class Ref, class Ptr>struct __list_iterator{typedef __list_iterator<T, const T&, const T*> const_iterator;typedef __list_iterator<T, T&, T*>             iterator;typedef __list_iterator<T, Ref, Ptr>           Self;typedef ListNode<T>* Node;Node _node;__list_iterator(Node node) : _node(node) {}__list_iterator() {}__list_iterator(const iterator& x) : _node(x._node) {}//重载bool operator==(const Self& x) const{return _node == x._node;}bool operator!=(const Self& x) const{return _node != x._node;}//解引用重载Ref operator*() const{return _node->data;}//箭头重载Ptr operator->(){return &(_node->data);//return &(operator*());}//前置++Self& operator++(){_node = _node->next;return *this;}//后置++Self operator++(int){Self tmp = *this;++ *this;return tmp;}//前置--Self& operator--(){_node = _node->prev;return *this;}//后置--Self operator--(int){Self tmp = *this;-- *this;return tmp;}};template <class T, class Ref, class Ptr>struct reverse__iterator{typedef reverse__iterator<T, const T&, const T*> const_reverse_iterator;typedef reverse__iterator<T, T&, T*>             reverse_iterator;typedef reverse__iterator<T, Ref, Ptr>           Self;typedef ListNode<T>* Node;Node _node;reverse__iterator(Node node) : _node(node) {}reverse__iterator() {}reverse__iterator(const reverse_iterator& x) : _node(x._node) {}//重载bool operator==(const Self& x) const{return _node == x._node;}bool operator!=(const Self& x) const{return _node != x._node;}//解引用重载Ref operator*() const{return _node->data;}//箭头重载Ptr operator->(){return &(_node->data);//return &(operator*());}//前置++Self& operator++(){_node = _node->prev;return *this;}//后置++Self operator++(int){Self tmp = *this;++* this;return tmp;}//前置--Self& operator--(){_node = _node->next;return *this;}//后置--Self operator--(int){Self tmp = *this;--* this;return tmp;}};template <class T>class list{public:typedef __list_iterator<T, T&, T*>             iterator;typedef __list_iterator<T, const T&, const T*> const_iterator;typedef reverse__iterator<T, const T&, const T*> const_reverse_iterator;typedef reverse__iterator<T, T&, T*>             reverse_iterator;void empty_init(){_head = new node;_head->next = _head;_head->prev = _head;}list(){empty_init();}~list(){clear();delete _head;_head = nullptr;}list(const list<T>& x){empty_init();/*iterator it = x.begin();while (it != x.end()){push_back(*it);}*/for (const auto& e : x){push_back(e);}}/*list<T>& operator=(const list<T>& x){if (this != &x){clear();for (const auto& e : x){push_back(e);}}return *this;}*/list<T>& operator=(list<T> x){swap(x);return *this;}//iterator begin(){//return iterator(_head->next);return _head->next;}iterator end(){//return iterator(_head);return _head;}reverse_iterator rbegin(){//return iterator(_head->next);return _head->prev;}reverse_iterator rend(){//return iterator(_head);return _head;}const_iterator begin() const{//return iterator(_head->next);return _head->next;}const_iterator end() const{//return iterator(_head);return _head;}//bool empty() const{//return _head->prev == _head;return _head->next == _head;}size_t size() const{size_t count = 0;const_iterator it = begin();while (it != end()){++count;++it;}return count;}//T& front(){return *(begin());}const T& front() const{return *(begin());}T& back(){return *(--end());}const T& back() const{return *(--end());}//void swap(list<T>& x){std::swap(_head, x._head);}iterator insert(iterator position, const T& val){assert(position._node);node* cur = position._node;node* prev = cur->prev;node* newnode = new node(val);prev->next = newnode;newnode->prev = prev;newnode->next = cur;cur->prev = newnode;//return iterator(newnode);return newnode;}iterator erase(iterator position){assert(position._node);assert(!empty());node* cur = position._node;node* next = cur->next;node* prev = cur->prev;delete cur;prev->next = next;next->prev = prev;//return iterator(next);return next;}void push_back(const T& val){node* tail = _head->prev;node* newnode = new node(val);tail->next = newnode;newnode->prev = tail;newnode->next = _head;_head->prev = newnode;}/*void push_back(const T& val){insert(end(), val);}*/void push_front(const T& val){node* cur = begin()._node;node* newnode = new node(val);_head->next = newnode;newnode->prev = _head;newnode->next = cur;cur->prev = newnode;}/*void push_front(const T& val){insert(begin(), val);}*/void pop_back(){assert(!empty());node* cur = _head->prev;node* prev = cur->prev;delete cur;prev->next = _head;_head->prev = prev;}/*void pop_back(){erase(--end());}*/void pop_front(){assert(!empty());node* cur = begin()._node;node* next = cur->next;delete cur;_head->next = next;next->prev = _head;}/*void pop_front(){erase(begin());}*/void resize(size_t n, T val = T()){if (n != size()){if (n > size()){size_t len = n - size();for (size_t i = 0; i < len; i++){push_back(val);}}else{size_t len = size() - n;for (size_t i = 0; i < len; i++){pop_back();}}}	}void clear(){assert(!empty());iterator it = begin();while (it != end()){it=erase(it);}}private:typedef ListNode<T> node;node* _head;};}

test.cpp//测试代码

#include<iostream>
using namespace std;#include"list.h"namespace lx
{void test2(){list<int> l1;l1.push_back(1);l1.push_back(2);l1.push_back(3);l1.push_back(4);l1.push_back(5);auto rit = l1.rbegin();while (rit != l1.rend()){cout << *rit << " ";++rit;}cout << endl;}
}int main()
{lx::test2();return 0;
}

来,我们看重点部分哈。

template <class T, class Ref, class Ptr>struct __list_iterator//正向迭代器的封装{typedef __list_iterator<T, const T&, const T*> const_iterator;typedef __list_iterator<T, T&, T*>             iterator;typedef __list_iterator<T, Ref, Ptr>           Self;typedef ListNode<T>* Node;Node _node;__list_iterator(Node node) : _node(node) {}__list_iterator() {}__list_iterator(const iterator& x) : _node(x._node) {}//重载bool operator==(const Self& x) const{return _node == x._node;}bool operator!=(const Self& x) const{return _node != x._node;}//解引用重载Ref operator*() const{return _node->data;}//箭头重载Ptr operator->(){return &(_node->data);//return &(operator*());}//前置++Self& operator++(){_node = _node->next;return *this;}//后置++Self operator++(int){Self tmp = *this;++ *this;return tmp;}//前置--Self& operator--(){_node = _node->prev;return *this;}//后置--Self operator--(int){Self tmp = *this;-- *this;return tmp;}};template <class T, class Ref, class Ptr>struct reverse__iterator//反向迭代器的封装{typedef reverse__iterator<T, const T&, const T*> const_reverse_iterator;typedef reverse__iterator<T, T&, T*>             reverse_iterator;typedef reverse__iterator<T, Ref, Ptr>           Self;typedef ListNode<T>* Node;Node _node;reverse__iterator(Node node) : _node(node) {}reverse__iterator() {}reverse__iterator(const reverse_iterator& x) : _node(x._node) {}//重载bool operator==(const Self& x) const{return _node == x._node;}bool operator!=(const Self& x) const{return _node != x._node;}//解引用重载Ref operator*() const{return _node->data;}//箭头重载Ptr operator->(){return &(_node->data);//return &(operator*());}//前置++Self& operator++(){_node = _node->prev;//这里不一样return *this;}//后置++Self operator++(int){Self tmp = *this;++* this;return tmp;}//前置--Self& operator--(){_node = _node->next;//这里不一样return *this;}//后置--Self operator--(int){Self tmp = *this;--* this;return tmp;}};

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

来,我们按照刚刚的思想重新写一遍代码。

reverse_iterator.h

#pragma once
namespace lx
{template<class iterator_type,class Ref,class Ptr>struct reverse__iterator{public:typedef reverse__iterator<iterator_type, Ref, Ptr> Self;reverse__iterator(const iterator_type& it):_it(it){}//重载bool operator==(const Self& x) const{return _it == x._it;}bool operator!=(const Self& x) const{return _it != x._it;}//解引用重载Ref operator*() const{return *_it;}//箭头重载Ptr operator->(){return &(operator*());}//前置++Self& operator++(){--_it;return *this;}//后置++Self operator++(int){Self tmp = *this;++* this;return tmp;}//前置--Self& operator--(){++_it;return *this;}//后置--Self operator--(int){Self tmp = *this;--* this;return tmp;}private:iterator_type _it;};
}

list.h

#pragma once
#include<cassert>
#include"reverse_iterator.h"
namespace lx
{template <class T>struct ListNode{ListNode<T>* next;ListNode<T>* prev;T data;ListNode(const T& x=T()):next(nullptr),prev(nullptr),data(x){}};template <class T, class Ref, class Ptr>struct __list_iterator{typedef __list_iterator<T, const T&, const T*> const_iterator;typedef __list_iterator<T, T&, T*>             iterator;typedef __list_iterator<T, Ref, Ptr>           Self;typedef ListNode<T>* Node;Node _node;__list_iterator(Node node) : _node(node) {}__list_iterator() {}__list_iterator(const iterator& x) : _node(x._node) {}//重载bool operator==(const Self& x) const{return _node == x._node;}bool operator!=(const Self& x) const{return _node != x._node;}//解引用重载Ref operator*() const{return _node->data;}//箭头重载Ptr operator->(){return &(_node->data);//return &(operator*());}//前置++Self& operator++(){_node = _node->next;return *this;}//后置++Self operator++(int){Self tmp = *this;++ *this;return tmp;}//前置--Self& operator--(){_node = _node->prev;return *this;}//后置--Self operator--(int){Self tmp = *this;-- *this;return tmp;}};//template <class T, class Ref, class Ptr>//struct reverse__iterator//{//	typedef reverse__iterator<T, const T&, const T*> const_reverse_iterator;//	typedef reverse__iterator<T, T&, T*>             reverse_iterator;//	typedef reverse__iterator<T, Ref, Ptr>           Self;//	typedef ListNode<T>* Node;//	Node _node;//	reverse__iterator(Node node) : _node(node) {}//	reverse__iterator() {}//	reverse__iterator(const reverse_iterator& x) : _node(x._node) {}//	//重载//	bool operator==(const Self& x) const//	{//		return _node == x._node;//	}//	bool operator!=(const Self& x) const//	{//		return _node != x._node;//	}//	//解引用重载//	Ref operator*() const//	{//		return _node->data;//	}//	//箭头重载//	Ptr operator->()//	{//		return &(_node->data);//		//return &(operator*());//	}//	//前置++//	Self& operator++()//	{//		_node = _node->prev;//		return *this;//	}//	//后置++//	Self operator++(int)//	{//		Self tmp = *this;//		++* this;//		return tmp;//	}//	//前置--//	Self& operator--()//	{//		_node = _node->next;//		return *this;//	}//	//后置--//	Self operator--(int)//	{//		Self tmp = *this;//		--* this;//		return tmp;//	}//};template <class T>class list{public:typedef __list_iterator<T, T&, T*>             iterator;typedef __list_iterator<T, const T&, const T*> const_iterator;typedef reverse__iterator<iterator, T&, T*>                         reverse_iterator;typedef reverse__iterator<const_iterator, const T&, const T*>       const_reverse_iterator;void empty_init(){_head = new node;_head->next = _head;_head->prev = _head;}list(){empty_init();}~list(){clear();delete _head;_head = nullptr;}list(const list<T>& x){empty_init();/*iterator it = x.begin();while (it != x.end()){push_back(*it);}*/for (const auto& e : x){push_back(e);}}/*list<T>& operator=(const list<T>& x){if (this != &x){clear();for (const auto& e : x){push_back(e);}}return *this;}*/list<T>& operator=(list<T> x){swap(x);return *this;}//iterator begin(){//return iterator(_head->next);return _head->next;}iterator end(){//return iterator(_head);return _head;}reverse_iterator rbegin(){return reverse_iterator(--end());}reverse_iterator rend(){return reverse_iterator(end());}const_iterator begin() const{//return iterator(_head->next);return _head->next;}const_iterator end() const{//return iterator(_head);return _head;}const_reverse_iterator rbegin() const{return reverse_iterator(--end());}const_reverse_iterator rend() const{return reverse_iterator(end());}//bool empty() const{//return _head->prev == _head;return _head->next == _head;}size_t size() const{size_t count = 0;const_iterator it = begin();while (it != end()){++count;++it;}return count;}//T& front(){return *(begin());}const T& front() const{return *(begin());}T& back(){return *(--end());}const T& back() const{return *(--end());}//void swap(list<T>& x){std::swap(_head, x._head);}iterator insert(iterator position, const T& val){assert(position._node);node* cur = position._node;node* prev = cur->prev;node* newnode = new node(val);prev->next = newnode;newnode->prev = prev;newnode->next = cur;cur->prev = newnode;//return iterator(newnode);return newnode;}iterator erase(iterator position){assert(position._node);assert(!empty());node* cur = position._node;node* next = cur->next;node* prev = cur->prev;delete cur;prev->next = next;next->prev = prev;//return iterator(next);return next;}void push_back(const T& val){node* tail = _head->prev;node* newnode = new node(val);tail->next = newnode;newnode->prev = tail;newnode->next = _head;_head->prev = newnode;}/*void push_back(const T& val){insert(end(), val);}*/void push_front(const T& val){node* cur = begin()._node;node* newnode = new node(val);_head->next = newnode;newnode->prev = _head;newnode->next = cur;cur->prev = newnode;}/*void push_front(const T& val){insert(begin(), val);}*/void pop_back(){assert(!empty());node* cur = _head->prev;node* prev = cur->prev;delete cur;prev->next = _head;_head->prev = prev;}/*void pop_back(){erase(--end());}*/void pop_front(){assert(!empty());node* cur = begin()._node;node* next = cur->next;delete cur;_head->next = next;next->prev = _head;}/*void pop_front(){erase(begin());}*/void resize(size_t n, T val = T()){if (n != size()){if (n > size()){size_t len = n - size();for (size_t i = 0; i < len; i++){push_back(val);}}else{size_t len = size() - n;for (size_t i = 0; i < len; i++){pop_back();}}}	}void clear(){assert(!empty());iterator it = begin();while (it != end()){it=erase(it);}}private:typedef ListNode<T> node;node* _head;};}

test.cpp//测试代码

#include<iostream>
using namespace std;
#include"reverse_iterator.h"
#include"list.h"
namespace lx
{void test2(){list<int> l1;l1.push_back(1);l1.push_back(2);l1.push_back(3);l1.push_back(4);l1.push_back(5);auto rit = l1.rbegin();while (rit != l1.rend()){cout << *rit << " ";++rit;}cout << endl;}
}int main()
{lx::test2();return 0;
}

那么重点部分肯定就是reverse_iterator.h

#pragma once
namespace lx
{template<class iterator_type,class Ref,class Ptr>struct reverse__iterator{public:typedef reverse__iterator<iterator_type, Ref, Ptr> Self;reverse__iterator(const iterator_type& it):_it(it){}//重载bool operator==(const Self& x) const{return _it == x._it;}bool operator!=(const Self& x) const{return _it != x._it;}//解引用重载Ref operator*() const{return *_it;}//箭头重载Ptr operator->(){return &(operator*());}//前置++Self& operator++(){--_it;return *this;}//后置++Self operator++(int){Self tmp = *this;++* this;return tmp;}//前置--Self& operator--(){++_it;return *this;}//后置--Self operator--(int){Self tmp = *this;--* this;return tmp;}private:iterator_type _it;};
}

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

如果按照源码那样设计,代码就得写成这样:(变动的地方我都在旁边注释出来了。大家简单画一下图就能明白遍历逻辑了)

reverse_iterator.h

#pragma once
//namespace lx
//{
//
//	template<class iterator_type,class Ref,class Ptr>
//	struct reverse__iterator
//	{
//	public:
//		typedef reverse__iterator<iterator_type, Ref, Ptr> Self;
//
//		reverse__iterator(const iterator_type& it)
//			:_it(it)
//		{}
//
//		//重载
//		bool operator==(const Self& x) const
//		{
//			return _it == x._it;
//		}
//		bool operator!=(const Self& x) const
//		{
//			return _it != x._it;
//		}
//
//		//解引用重载
//		Ref operator*() const
//		{
//			return *_it;
//		}
//		//箭头重载
//		Ptr operator->()
//		{
//			return &(operator*());
//		}
//
//		//前置++
//		Self& operator++()
//		{
//			--_it;
//			return *this;
//		}
//		//后置++
//		Self operator++(int)
//		{
//			Self tmp = *this;
//			++* this;
//			return tmp;
//		}
//
//		//前置--
//		Self& operator--()
//		{
//			++_it;
//			return *this;
//		}
//		//后置--
//		Self operator--(int)
//		{
//			Self tmp = *this;
//			--* this;
//			return tmp;
//		}
//	private:
//		iterator_type _it;
//	};
//}namespace lx
{template<class iterator_type, class Ref, class Ptr>struct reverse__iterator{public:typedef reverse__iterator<iterator_type, Ref, Ptr> Self;reverse__iterator(const iterator_type& it):_it(it){}//重载bool operator==(const Self& x) const{return _it == x._it;}bool operator!=(const Self& x) const{return _it != x._it;}//解引用重载Ref operator*() const//这里变动了{iterator_type tmp = _it;--tmp;return *tmp;}//箭头重载Ptr operator->(){return &(operator*());}//前置++Self& operator++(){--_it;return *this;}//后置++Self operator++(int){Self tmp = *this;++* this;return tmp;}//前置--Self& operator--(){++_it;return *this;}//后置--Self operator--(int){Self tmp = *this;--* this;return tmp;}private:iterator_type _it;};
}

list.h

#pragma once
#include<cassert>
#include"reverse_iterator.h"
namespace lx
{template <class T>struct ListNode{ListNode<T>* next;ListNode<T>* prev;T data;ListNode(const T& x=T()):next(nullptr),prev(nullptr),data(x){}};template <class T, class Ref, class Ptr>struct __list_iterator{typedef __list_iterator<T, const T&, const T*> const_iterator;typedef __list_iterator<T, T&, T*>             iterator;typedef __list_iterator<T, Ref, Ptr>           Self;typedef ListNode<T>* Node;Node _node;__list_iterator(Node node) : _node(node) {}__list_iterator() {}__list_iterator(const iterator& x) : _node(x._node) {}//重载bool operator==(const Self& x) const{return _node == x._node;}bool operator!=(const Self& x) const{return _node != x._node;}//解引用重载Ref operator*() const{return _node->data;}//箭头重载Ptr operator->(){return &(_node->data);//return &(operator*());}//前置++Self& operator++(){_node = _node->next;return *this;}//后置++Self operator++(int){Self tmp = *this;++ *this;return tmp;}//前置--Self& operator--(){_node = _node->prev;return *this;}//后置--Self operator--(int){Self tmp = *this;-- *this;return tmp;}};//template <class T, class Ref, class Ptr>//struct reverse__iterator//{//	typedef reverse__iterator<T, const T&, const T*> const_reverse_iterator;//	typedef reverse__iterator<T, T&, T*>             reverse_iterator;//	typedef reverse__iterator<T, Ref, Ptr>           Self;//	typedef ListNode<T>* Node;//	Node _node;//	reverse__iterator(Node node) : _node(node) {}//	reverse__iterator() {}//	reverse__iterator(const reverse_iterator& x) : _node(x._node) {}//	//重载//	bool operator==(const Self& x) const//	{//		return _node == x._node;//	}//	bool operator!=(const Self& x) const//	{//		return _node != x._node;//	}//	//解引用重载//	Ref operator*() const//	{//		return _node->data;//	}//	//箭头重载//	Ptr operator->()//	{//		return &(_node->data);//		//return &(operator*());//	}//	//前置++//	Self& operator++()//	{//		_node = _node->prev;//		return *this;//	}//	//后置++//	Self operator++(int)//	{//		Self tmp = *this;//		++* this;//		return tmp;//	}//	//前置--//	Self& operator--()//	{//		_node = _node->next;//		return *this;//	}//	//后置--//	Self operator--(int)//	{//		Self tmp = *this;//		--* this;//		return tmp;//	}//};template <class T>class list{public:typedef __list_iterator<T, T&, T*>             iterator;typedef __list_iterator<T, const T&, const T*> const_iterator;typedef reverse__iterator<iterator, T&, T*>                         reverse_iterator;typedef reverse__iterator<const_iterator, const T&, const T*>       const_reverse_iterator;void empty_init(){_head = new node;_head->next = _head;_head->prev = _head;}list(){empty_init();}~list(){clear();delete _head;_head = nullptr;}list(const list<T>& x){empty_init();/*iterator it = x.begin();while (it != x.end()){push_back(*it);}*/for (const auto& e : x){push_back(e);}}/*list<T>& operator=(const list<T>& x){if (this != &x){clear();for (const auto& e : x){push_back(e);}}return *this;}*/list<T>& operator=(list<T> x){swap(x);return *this;}//iterator begin(){//return iterator(_head->next);return _head->next;}iterator end(){//return iterator(_head);return _head;}/*reverse_iterator rbegin(){return reverse_iterator(--end());}reverse_iterator rend(){return reverse_iterator(end());}*/reverse_iterator rbegin(){return reverse_iterator(end());//这里变动了}reverse_iterator rend(){return reverse_iterator(begin());//这里变动了}const_iterator begin() const{//return iterator(_head->next);return _head->next;}const_iterator end() const{//return iterator(_head);return _head;}/*const_reverse_iterator rbegin() const{return reverse_iterator(--end());}const_reverse_iterator rend() const{return reverse_iterator(end());}*/const_reverse_iterator rbegin() const{return reverse_iterator(end());//这里变动了}const_reverse_iterator rend() const{return reverse_iterator(begin());//这里变动了}//bool empty() const{//return _head->prev == _head;return _head->next == _head;}size_t size() const{size_t count = 0;const_iterator it = begin();while (it != end()){++count;++it;}return count;}//T& front(){return *(begin());}const T& front() const{return *(begin());}T& back(){return *(--end());}const T& back() const{return *(--end());}//void swap(list<T>& x){std::swap(_head, x._head);}iterator insert(iterator position, const T& val){assert(position._node);node* cur = position._node;node* prev = cur->prev;node* newnode = new node(val);prev->next = newnode;newnode->prev = prev;newnode->next = cur;cur->prev = newnode;//return iterator(newnode);return newnode;}iterator erase(iterator position){assert(position._node);assert(!empty());node* cur = position._node;node* next = cur->next;node* prev = cur->prev;delete cur;prev->next = next;next->prev = prev;//return iterator(next);return next;}void push_back(const T& val){node* tail = _head->prev;node* newnode = new node(val);tail->next = newnode;newnode->prev = tail;newnode->next = _head;_head->prev = newnode;}/*void push_back(const T& val){insert(end(), val);}*/void push_front(const T& val){node* cur = begin()._node;node* newnode = new node(val);_head->next = newnode;newnode->prev = _head;newnode->next = cur;cur->prev = newnode;}/*void push_front(const T& val){insert(begin(), val);}*/void pop_back(){assert(!empty());node* cur = _head->prev;node* prev = cur->prev;delete cur;prev->next = _head;_head->prev = prev;}/*void pop_back(){erase(--end());}*/void pop_front(){assert(!empty());node* cur = begin()._node;node* next = cur->next;delete cur;_head->next = next;next->prev = _head;}/*void pop_front(){erase(begin());}*/void resize(size_t n, T val = T()){if (n != size()){if (n > size()){size_t len = n - size();for (size_t i = 0; i < len; i++){push_back(val);}}else{size_t len = size() - n;for (size_t i = 0; i < len; i++){pop_back();}}}	}void clear(){assert(!empty());iterator it = begin();while (it != end()){it=erase(it);}}private:typedef ListNode<T> node;node* _head;};}

test.cpp//这个没变

#include<iostream>
using namespace std;
#include"reverse_iterator.h"
#include"list.h"namespace lx
{void test2(){list<int> l1;l1.push_back(1);l1.push_back(2);l1.push_back(3);l1.push_back(4);l1.push_back(5);auto rit = l1.rbegin();while (rit != l1.rend()){cout << *rit << " ";++rit;}cout << endl;}
}int main()
{lx::test2();return 0;
}

同理在vector容器中也是一样:也就是我说的使用容器适配器思想写一个“万能的”反向迭代器。
reverse_iterator.h

#pragma once
//namespace lx
//{
//
//	template<class iterator_type,class Ref,class Ptr>
//	struct reverse__iterator
//	{
//	public:
//		typedef reverse__iterator<iterator_type, Ref, Ptr> Self;
//
//		reverse__iterator(const iterator_type& it)
//			:_it(it)
//		{}
//
//		//重载
//		bool operator==(const Self& x) const
//		{
//			return _it == x._it;
//		}
//		bool operator!=(const Self& x) const
//		{
//			return _it != x._it;
//		}
//
//		//解引用重载
//		Ref operator*() const
//		{
//			return *_it;
//		}
//		//箭头重载
//		Ptr operator->()
//		{
//			return &(operator*());
//		}
//
//		//前置++
//		Self& operator++()
//		{
//			--_it;
//			return *this;
//		}
//		//后置++
//		Self operator++(int)
//		{
//			Self tmp = *this;
//			++* this;
//			return tmp;
//		}
//
//		//前置--
//		Self& operator--()
//		{
//			++_it;
//			return *this;
//		}
//		//后置--
//		Self operator--(int)
//		{
//			Self tmp = *this;
//			--* this;
//			return tmp;
//		}
//	private:
//		iterator_type _it;
//	};
//}namespace lx
{template<class iterator_type, class Ref, class Ptr>struct reverse__iterator{public:typedef reverse__iterator<iterator_type, Ref, Ptr> Self;reverse__iterator(const iterator_type& it):_it(it){}//重载bool operator==(const Self& x) const{return _it == x._it;}bool operator!=(const Self& x) const{return _it != x._it;}//解引用重载Ref operator*() const{iterator_type tmp = _it;--tmp;return *tmp;}//箭头重载Ptr operator->(){return &(operator*());}//前置++Self& operator++(){--_it;return *this;}//后置++Self operator++(int){Self tmp = *this;++* this;return tmp;}//前置--Self& operator--(){++_it;return *this;}//后置--Self operator--(int){Self tmp = *this;--* this;return tmp;}private:iterator_type _it;};
}

vector.h

#pragma once
#include<cassert>	
#include"reverse_iterator.h"
namespace lx
{template<class T>class vector{public:typedef T* iterator;typedef const T* const_iterator;typedef reverse__iterator<iterator, T&, T*>                         reverse_iterator;typedef reverse__iterator<const_iterator, const T&, const T*>       const_reverse_iterator;/*vector():_start(nullptr), _finish(nullptr), _end_of_storage(nullptr){}*///因为我们在成员变量那里给了缺省值,这个缺省值就是给初始化列表使用的//所以我们就可以写成下面那样,简洁些。当然,你也可以写成上面那样。vector() {}//默认构造~vector(){if (_start){delete[] _start;_start = nullptr;_finish = nullptr;_end_of_storage = nullptr;}}/*vector(const vector& x)//拷贝构造传统写法{size_t x_size = x.size();size_t x_capacity = x.capacity();_start = new T[x_capacity];_finish = _start + x_size;_end_of_storage = _start + x_capacity;for (size_t i = 0; i < x_size; i++){_start[i] = x[i];}}*/vector(const vector& x)//拷贝构造现代写法{reserve(x.capacity());/*for (size_t i = 0; i < x.size(); i++){push_back(x[i]);}*/for (const auto& e : x){push_back(e);}}template <class InputIterator>vector(InputIterator first, InputIterator last){while (first != last){push_back(*first);++first;}}vector(size_t n, const T& val = T()){resize(n, val);}vector(int n, const T& val = T()){resize(n, val);}vector<T>& operator=(const vector<T>& x)//赋值重载传统写法{size_t x_size = x.size();size_t x_capacity = x.capacity();delete[] _start;_start = new T[x_capacity];_finish = _start + x_size;_end_of_storage = _start + x_capacity;for (size_t i = 0; i < x_size; i++){_start[i] = x[i];}return *this;}//vector<T>& operator=(vector<T> x)//赋值重载现代写法//{//	swap(x);//	return *this;//}//Iterators:iterator begin(){return _start;}const_iterator begin() const{return _start;}iterator end(){return _finish;}const_iterator end() const{return _finish;}//这里是反向迭代器reverse_iterator rbegin(){return reverse_iterator(end());}reverse_iterator rend(){return reverse_iterator(begin());}const_reverse_iterator rbegin() const{return reverse_iterator(end());}const_reverse_iterator rend() const{return reverse_iterator(begin());}//Capacity:size_t size() const{return size_t(end() - begin());}size_t capacity() const{return size_t(_end_of_storage - begin());}bool empty() const{return begin() == end();}void reserve(size_t n){if (n > capacity()){size_t old_size = size();T* tmp = new T[n];for (size_t i = 0; i < old_size; i++){tmp[i] = _start[i];}delete[] _start;_start = tmp;_finish = _start + old_size;_end_of_storage = _start + n;}}void resize(size_t n, T val = T()){size_t old_size = size();if (n > old_size){reserve(n);for (size_t i = old_size; i < n; i++){_start[i] = val;++_finish;}}else{//_finish = _finish - (old_size - n);_finish = _start + n;}}/*void resize(size_t n, T val = T()){if (n > size()){reserve(n);while (_finish < _start + n){*_finish = val;++_finish;}}else{_finish = _start + n;}}*///Element access://元素访问T& front(){return *begin();}const T& front() const{return *begin();}T& back(){return *(end() - 1);}const T& back() const{return *(end() - 1);}T& operator[](size_t n){return *(begin() + n);}const T& operator[](size_t n) const{return *(begin() + n);}//Modifiers:void push_back(const T& val){if (end() == _end_of_storage){size_t newcapacity = capacity() == 0 ? 4 : capacity() * 2;reserve(newcapacity);}//_start[size()] = val;*_finish = val;++_finish;}void pop_back(){assert(!empty());--_finish;}iterator insert(iterator position, const T& val){assert(position <= _finish);assert(position >= _start);if (end() == _end_of_storage){size_t len = position - _start;size_t newcapacity = capacity() == 0 ? 4 : capacity() * 2;reserve(newcapacity);position = _start + len;}iterator finish = end();while (finish != position){*finish = *(finish - 1);--finish;}*position = val;++_finish;return position;}iterator erase(iterator position){assert(position <= _finish);assert(position >= _start);assert(!empty());iterator pos = position;while (pos != end()){*pos = *(pos + 1);++pos;}--_finish;return position;}void swap(vector<T>& x){std::swap(_start, x._start);std::swap(_finish, x._finish);std::swap(_end_of_storage, x._end_of_storage);}private:iterator _start = nullptr;iterator _finish = nullptr;iterator _end_of_storage = nullptr;};}

test.cpp

#include<iostream>
using namespace std;
#include"reverse_iterator.h"
#include"vector.h"
namespace lx
{void test3(){vector<int> l1;l1.push_back(1);l1.push_back(2);l1.push_back(3);l1.push_back(4);l1.push_back(5);auto rit = l1.rbegin();while (rit != l1.rend()){cout << *rit << " ";++rit;}cout << endl;}
}int main()
{lx::test3();return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/90450.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/90450.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【一步步ai】数据增强与预处理

提升NL2SQL系统性能是一个复杂的多维度优化问题&#xff0c;涉及数据工程、模型架构、训练策略和评估方法等多个层面。以下是一些有效的提升方向和具体方法&#xff1a; 一、数据增强与预处理 多样化数据生成 模板扩展&#xff1a;基于SQL语法模板自动生成多样化的NL-SQL对&am…

站在哪个肩膀上开始学习卡尔曼滤波

站在哪个肩膀上开始学习卡尔曼滤波前言从自适应滤波的角度正交性原理到维纳解kalman滤波的提出innovation process新息过程kalman滤波算法Kalman 自适应滤波器算法初始条件输入观测向量过程已知参数计算&#xff1a;n1&#xff0c;2&#xff0c;3&#xff0c;..参考前言 不知道…

什么是FCR,如何提升FCR?

‌ FCR&#xff08;First Call Resolution&#xff0c;首次呼叫解决率&#xff09;&#xff0c;意思是指客户首次联系客服时&#xff0c;问题在单次交互中被完全解决的比率。‌ ‌FCR &#xff08;首次解决的通话量 / 总首次通话量&#xff09; 100%一、关键要点&…

【浏览器插件冲突】Edge浏览器加载不出来CSDN创作者中心

【浏览器插件冲突】Edge浏览器加载不出来CSDN创作者中心写在最前面报错GPT的全部回复&#xff0c;可以参考&#x1f50d; 具体错误解释&#xff1a;1. **CORS错误**2. **XHR 请求失败**3. **ReaderArticleFinder / Readability**&#x1f6e0;️ 为什么页面没有内容显示&#x…

从零开发Java坦克大战:架构设计与难点突破 (下)

6. 游戏引擎类:6.1 完整源码展示: import javax.swing.*; import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.ArrayList; import java.util.HashSet; import java.util.Random; import java.util.Set;public class Gam…

Git下载与安装全攻略

引言 Git是当今最流行的分布式版本控制系统&#xff0c;由Linus Torvalds于2005年创建。它帮助开发者高效管理代码变更&#xff0c;支持多人协作开发&#xff0c;是现代软件开发不可或缺的工具。无论是个人项目还是团队协作&#xff0c;Git都能提供强大的版本控制功能。 本文…

【Elasticsearch】快照生命周期管理 SLM(理论篇)

《Elasticsearch 集群》系列&#xff0c;共包含以下文章&#xff1a; 1️⃣ 冷热集群架构2️⃣ 合适的锅炒合适的菜&#xff1a;性能与成本平衡原理公式解析3️⃣ ILM&#xff08;Index Lifecycle Management&#xff09;策略详解4️⃣ Elasticsearch 跨机房部署5️⃣ 快照与恢…

深入理解 UDP 协议:从原理到实战的技术解析

UDP&#xff08;User Datagram Protocol&#xff0c;用户数据报协议&#xff09;作为 TCP 的 "轻量型伙伴"&#xff0c;在实时通信、流媒体传输等场景中发挥着不可替代的作用。与 TCP 的可靠传输不同&#xff0c;UDP 以 "简单、快速、无连接" 为设计理念&a…

c语言-数据结构-沿顺相同树解决对称二叉树问题的两种思路

二叉树OJ前言对称二叉树前言 本篇继续讲解二叉树OJ题目之对称二叉树 对称二叉树 题目链接&#xff1a;https://leetcode.cn/problems/symmetric-tree/description/ 该题要求比较这棵树是否对称&#xff0c;对称&#xff0c;指的是结构对称并且值也要对称&#xff0c;即对应…

云原生可观测-日志观测(Loki)最佳实践

一、Loki 简介 云原生可观测三大支柱 支柱工具用途MetricsPrometheus性能趋势、系统负载LogsLoki原始事件记录、错误诊断TracesTempo / Jaeger分布式链路追踪 一、Loki 简介 1.1 Loki 是什么 Loki 是由 Grafana Labs 开发的 日志聚合系统&#xff0c;与 Prometheus 架构一…

Windows Server 2003 R2系统C盘扩容教程

一、PAGreen软件下载 下载地址&#xff1a; ExtPart.zip https://pan.baidu.com/s/1FxK61XNI0t-4JIEWK1QA8Q?pwd8888 提取码: 8888 二、将软件解压缩 (1)、执行步骤一下载的程序 双击下图所示可执行程序 (2)、选择好解压路径&#xff0c;点击「Unzip」进行解压缩 (3)、磁…

Kubernetes配置管理

目录什么是ConfigMap创建ConfigMap1&#xff1a;基于目录创建ConfigMap1.创建conf目录&#xff0c;放置文件2.基于目录下的所有文件创建ConfigMap3.查看当前创建的ConfigMap2&#xff1a;基于文件创建ConfigMap1.单个文件创建ConfigMap2.使用带有key的命令创建ConfigMap3.多个文…

golang怎么实现每秒100万个请求(QPS),相关系统架构设计详解

一.需求 使用Golang,以Gin框架为基础,设计一个能够处理每秒100万请求(QPS 1M)的系统架构 注意:100万QPS是一个很高的数字,单机通常难以处理,所以必须采用分布式架构,并且需要多层次的架构设计和优化 二.搭建步骤 1.系统架构设计 为了实现高并发,需要考虑以下几个方面…

HCIA再复习

第一章.网络基础1.1 网络类型分类网络按照二层链路类型分为以下四种&#xff1a;多点接入网络&#xff08;MA&#xff09;&#xff1a;1&#xff0c;广播型多点接入&#xff08;BMA&#xff09;&#xff1a;如以太网&#xff0c;支持广播&#xff0c;设备通过MAC地址通信&#…

Qt 数据库连接池实现与管理

在 Qt 应用程序中&#xff0c;频繁创建和销毁数据库连接会带来显著的性能开销。数据库连接池通过复用现有连接&#xff0c;避免重复创建和销毁连接的开销&#xff0c;从而提高应用程序的响应速度和吞吐量。本文将详细介绍 Qt 中数据库连接池的实现与管理方法。 一、数据库连接池…

数据采集分析:从信息洪流中掘金的科学与艺术

——如何将原始数据转化为商业决策的黄金&#xff1f;&#x1f310; 引言&#xff1a;我们正淹没在数据的海洋&#xff0c;却渴求着知识的甘泉每天全球产生 2.5万亿字节 数据&#xff08;相当于每秒下载4.5万部高清电影&#xff09;&#xff0c;但未经分析的数据如同未提炼的原…

Oracle国产化替代:一线DBA的技术决策突围战

从“如履薄冰”到“游刃有余”,中国数据库的自主之路正重塑技术人的思维地图。 “凌晨三点的最后一次数据校验通过,割接系统绿灯全亮——**河北移动核心账务系统的Oracle数据库已被GoldenDB完全替代**。”2025年6月底,这场持续两年的攻坚战画上句号。当全省业务流量平稳切…

OS19.【Linux】进程状态(1)

目录 1.情景引入 2.操作系统学科对进程状态的分类 运行状态 基于时间片的轮转调度算法 阻塞状态 等待IO设备的例子 等待其他进程中需要获取的数据 进程唤醒 挂起状态(全称为阻塞挂起状态) 简单谈谈虚拟内存管理 就绪状态 笔面试题 3.Linux对进程状态的分类 R和S状…

Hadoop小文件合并技术深度解析:HAR文件归档、存储代价与索引结构

HDFS小文件问题的背景与挑战在Hadoop分布式文件系统&#xff08;HDFS&#xff09;的设计哲学中&#xff0c;"大文件、流式访问"是核心原则。然而现实场景中&#xff0c;海量小文件&#xff08;通常指远小于HDFS默认块大小128MB的文件&#xff09;的涌入却成为系统性能…

Verilog 提取信号的上升沿或者下降沿

上升沿提取代码&#xff1a;reg [1:0] F1;always (posedge clk)beginif(rst_n 1b0) F1[1:0]<2b00;else F1[1:0]<{F1[0],start_i};endwire start_l2h (F1[1:0]2b01)?1b1:1b0;下降沿提取代码&#xff1a;reg [1:0] F1;always (posedge clk)b…