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
英文地址,請注明出處:http://en.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…