C++反向迭代器的封装和模板进阶(个人笔记)

慈云数据 2024-04-23 技术支持 50 0

C++反迭代器和模板进阶

    • 1.反向迭代器
    • 2.模板
      • 2.1非类型模板参数
      • 2.2模板的特化
        • 2.2.1函数模板
        • 2.2.2类模板特化
          • 2.2.2.1 全特化
          • 2.2.2.1 偏特化
          • 2.3模板的分离编译
          • 2.4模板的优缺点

            1.反向迭代器

            用正向迭代器适配出反向迭代器

            这里是自己实现的反向迭代器版本,与STL标准库里的有点不太一样

            #pragma once
            template
            class ReverseIterator
            {
            	typedef ReverseIterator Self;
            public:
            	ReverseIterator(Iterator it)
            		:_it(it)
            	{}
            	Self& operator++()
            	{
            		--_it;
            		return *this;
            	}
            	Self& operator--()
            	{
            		++_it;
            		return *this;
            	}
            	Ref operator*()
            	{
            		return *_it;//无论是正向迭代器还是反向迭代器所指向的元素都一样
            	}
            	Ptr operator->()
            	{
            		return _it.operator->();//显示调用,无论是正向迭代器还是反向迭代器所指向的地址都一样
            	}
            	bool operator!=(const Self& s)
            	{
            		return _it != s._it;
            	}
            private:
            	Iterator _it;
            };
            

            这里是STL标准库里实现的反向迭代器

            #pragma once
            template
            class ReverseIterator
            {
            public:
            	typedef ReverseIterator Self;
            	ReverseIterator(Iterator it)
            		:_it(it)
            	{}
            	Self& operator++()
            	{
            		--_it;
            		return *this;
            	}
            	Self& operator--()
            	{
            		++_it;
            		return *this;
            	}
            	Ref operator*()//主要是这里不太一样,这里其实是先访问迭代器之前的元素,再让迭代器指向这,而自己写的是先让迭代器指向这,再访问迭代器指向的元素
            	{
            		Iterator cur = _it;
            		return *(--cur);
            	}
            	Ptr operator->()
            	{
            		return _it->operator*();
            	}
            	bool operator!=(const Self& s)
            	{
            		return _it != s._it;
            	}
            	bool operator==(const Self& s)
            	{
            		return _it == s._it;
            	}
            private:
            	Iterator _it;
            };
            

            下面是在vector和list实现的基础上再加入反向迭代器,也是分两个版本,自己实现的版本,和库里的版本

            自己实现的vector反向迭代器

            在这里插入图片描述

            #pragma once
            #include
            #include
            #include
            #include
            using namespace std;
            #include"reverse_iterator_copy.h"
            namespace ljh
            {
            	template
            	class vector
            	{
            	public:
            		typedef T* iterator;
            		typedef const T* const_iterator;
            		typedef ReverseIterator reverse_iterator;
            		typedef ReverseIterator const_reverse_iterator;
            		reverse_iterator rbegin()
            		{
            			return reverse_iterator(end() - 1);
            		}
            		reverse_iterator rend()
            		{
            			return reverse_iterator(begin() - 1);
            		}
            		const_reverse_iterator rbegin()const
            		{
            			return const_reverse_iterator(end() - 1);
            		}
            		const_reverse_iterator rend() const
            		{
            			return const_reverse_iterator(begin() - 1);
            		}
            		iterator begin()
            		{
            			return _start;
            		}
            		iterator end()
            		{
            			return _finish;
            		}
            		const_iterator begin() const
            		{
            			return _start;
            		}
            		const_iterator end() const
            		{
            			return _finish;
            		}
            		vector()
            		{}
            		template
            		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  capacity())
            			{
            				T* tmp = new T[n];
            				size_t sz = size();
            				if (_start)
            				{
            					for (size_t i = 0;i = _start);
            			assert(pos  
            

            库里实现的反向迭代器

            在这里插入图片描述

            #pragma once
            #pragma once
            #include
            #include
            #include
            #include
            using namespace std;
            #include"reverse_iterator.h"
            namespace ljh
            {
            	template
            	class vector
            	{
            	public:
            		typedef T* iterator;
            		typedef const T* const_iterator;
            		typedef ReverseIterator reverse_iterator;
            		typedef ReverseIterator const_reverse_iterator;
            		reverse_iterator rbegin()
            		{
            			return reverse_iterator(end());
            		}
            		reverse_iterator rend()
            		{
            			return reverse_iterator(begin());
            		}
            		const_reverse_iterator rbegin()const
            		{
            			return const_reverse_iterator(end());
            		}
            		const_reverse_iterator rend() const
            		{
            			return const_reverse_iterator(begin());
            		}
            		iterator begin()
            		{
            			return _start;
            		}
            		iterator end()
            		{
            			return _finish;
            		}
            		const_iterator begin() const
            		{
            			return _start;
            		}
            		const_iterator end() const
            		{
            			return _finish;
            		}
            		vector()
            		{}
            		template
            		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  capacity())
            			{
            				T* tmp = new T[n];
            				size_t sz = size();
            				if (_start)
            				{
            					for (size_t i = 0;i = _start);
            			assert(pos  
            

            自己实现的list反向迭代器

            在这里插入图片描述

            #pragma once
            #include
            #include
            using namespace std;
            #include
            #include
            #include"reverse_iterator.h"
            namespace ljh
            {
            	template
            	struct list_node
            	{
            		list_node(const T& x = T())
            			:_date(x)
            			,_next(nullptr)
            			,_prev(nullptr)
            		{}
            	public:
            		T _date;
            		list_node* _next;
            		list_node* _prev;
            	};
            	//T T& T*
            	//T const T& const T*
            	template
            	struct __list_iterator
            	{
            		typedef list_node Node;
            		typedef __list_iterator self;
            		Node* _node;
            		__list_iterator(Node* node)
            			:_node(node)
            		{}
            		self& operator++()
            		{
            			_node = _node->_next;
            			return *this;
            		}
            		self& operator--()
            		{
            			_node = _node->_prev;
            			return *this;
            		}
            		self operator++(int)
            		{
            			self tmp(*this);
            			_node = _node->_next;;
            			return tmp;
            		}
            		self operator--(int)
            		{
            			self tmp(*this);
            			_node = _node->_prev;
            			return tmp;
            		}
            		Ref operator* ()
            		{
            			return _node->_date;
            		}
            		Ptr operator->()
            		{
            			return &(_node->_date);
            		}
            		bool operator!=(const self& s)
            		{
            			return _node != s._node;
            		}
            		bool operator==(const self& s)
            		{
            			return _node == s._node;
            		}
            	public:
            	};
            	template
            	class list
            	{
            		typedef list_node Node;
            	public:
            		typedef __list_iterator iterator;
            		typedef __list_iterator const_iterator;
            		typedef ReverseIterator reverse_iterator;
            		typedef ReverseIterator const_reverse_iterator;
            		reverse_iterator rbegin()
            		{
            			return reverse_iterator(--end());
            		}
            		reverse_iterator rend()
            		{
            			return reverse_iterator(end());
            		}
            		const_reverse_iterator rbegin() const
            		{
            			return const_reverse_iterator(--end());
            		}
            		const_reverse_iterator rend() const
            		{
            			return const_reverse_iterator(end());
            		}
            		const_iterator begin() const
            		{
            			return const_iterator(_head->_next);
            		}
            		const_iterator end() const
            		{
            			return const_iterator(_head);
            		}
            		iterator begin()
            		{
            			return iterator(_head->_next);
            		}
            		iterator end()
            		{
            			return iterator(_head);
            		}
            		void empty_init()
            		{
            			_head = new Node;
            			_size = 0;
            			_head->_next=_head;
            			_head->_prev = _head;
            		}
            		list()
            		{
            			empty_init();
            		}
            		void swap(list& lt)
            		{
            			std::swap(_head, lt._head);
            			std::swap(_size, lt._size);
            		}
            		//lt2(lt1)
            		list(const list& lt)
            		{
            			empty_init();
            			for (auto e : lt)
            			{
            				push_back(e);
            			}
            		}
            		//lt2=lt1
            		list& operator=(list lt)
            		{
            			swap(lt);
            			return *this;
            		}
            		~list()
            		{
            			clear();
            			delete _head;
            			_head = nullptr;
            			_size = 0;
            		}
            		void clear()
            		{
            			iterator it = begin();
            			while (it != end())
            			{
            				it = erase(it);
            			}
            		}
            		void push_back(const T& x)
            		{
            			insert(end(), x);
            		}
            		void push_front(const T& x)
            		{
            			insert(begin(), x);
            		}
            		void pop_front()
            		{
            			erase(begin());
            		}
            		void pop_back()
            		{
            			erase(--end());
            		}
            		iterator insert(iterator pos, const T& x)
            		{
            			Node* cur = pos._node;
            			Node* newnode = new Node(x);
            			Node* prev = cur->_prev;
            			prev->_next = newnode;
            			newnode->_next = cur;
            			cur->_prev = newnode;
            			newnode->_prev = prev;
            			++_size;
            			return iterator(newnode);
            		}
            		iterator erase(iterator pos)
            		{
            			Node* cur = pos._node;
            			Node* next = cur->_next;
            			Node* prev = cur->_prev;
            			delete cur;
            			next->_prev = prev;
            			prev->_next = next;
            			--_size;
            			return iterator(next);
            		}
            		size_t size()
            		{
            			return _size;
            		}
            	private:
            		Node* _head;
            		size_t _size;
            	};
            }
            

            库里实现的list反向迭代器

            在这里插入图片描述

            #pragma once
            #pragma once
            #include
            #include
            using namespace std;
            #include
            #include
            #include"reverse_iterator.h"
            namespace ljh
            {
            	template
            	struct list_node
            	{
            		list_node(const T& x = T())
            			:_date(x)
            			, _next(nullptr)
            			, _prev(nullptr)
            		{}
            	public:
            		T _date;
            		list_node* _next;
            		list_node* _prev;
            	};
            	//T T& T*
            	//T const T& const T*
            	template
            	struct __list_iterator
            	{
            		typedef list_node Node;
            		typedef __list_iterator self;
            		Node* _node;
            		__list_iterator(Node* node)
            			:_node(node)
            		{}
            		self& operator++()
            		{
            			_node = _node->_next;
            			return *this;
            		}
            		self& operator--()
            		{
            			_node = _node->_prev;
            			return *this;
            		}
            		self operator++(int)
            		{
            			self tmp(*this);
            			_node = _node->_next;;
            			return tmp;
            		}
            		self operator--(int)
            		{
            			self tmp(*this);
            			_node = _node->_prev;
            			return tmp;
            		}
            		Ref operator* ()
            		{
            			return _node->_date;
            		}
            		Ptr operator->()
            		{
            			return &(_node->_date);
            		}
            		bool operator!=(const self& s)
            		{
            			return _node != s._node;
            		}
            		bool operator==(const self& s)
            		{
            			return _node == s._node;
            		}
            	public:
            	};
            	template
            	class list
            	{
            		typedef list_node Node;
            	public:
            		typedef __list_iterator iterator;
            		typedef __list_iterator const_iterator;
            		typedef ReverseIterator reverse_iterator;
            		typedef ReverseIterator const_reverse_iterator;
            		reverse_iterator rbegin()
            		{
            			return reverse_iterator(end());
            		}
            		reverse_iterator rend()
            		{
            			return reverse_iterator(begin());
            		}
            		const_reverse_iterator rbegin() const
            		{
            			return const_reverse_iterator(end());
            		}
            		const_reverse_iterator rend() const
            		{
            			return const_reverse_iterator(begin());
            		}
            		const_iterator begin() const
            		{
            			return const_iterator(_head->_next);
            		}
            		const_iterator end() const
            		{
            			return const_iterator(_head);
            		}
            		iterator begin()
            		{
            			return iterator(_head->_next);
            		}
            		iterator end()
            		{
            			return iterator(_head);
            		}
            		void empty_init()
            		{
            			_head = new Node;
            			_size = 0;
            			_head->_next = _head;
            			_head->_prev = _head;
            		}
            		list()
            		{
            			empty_init();
            		}
            		void swap(list& lt)
            		{
            			std::swap(_head, lt._head);
            			std::swap(_size, lt._size);
            		}
            		//lt2(lt1)
            		list(const list& lt)
            		{
            			empty_init();
            			for (auto e : lt)
            			{
            				push_back(e);
            			}
            		}
            		//lt2=lt1
            		list& operator=(list lt)
            		{
            			swap(lt);
            			return *this;
            		}
            		~list()
            		{
            			clear();
            			delete _head;
            			_head = nullptr;
            			_size = 0;
            		}
            		void clear()
            		{
            			iterator it = begin();
            			while (it != end())
            			{
            				it = erase(it);
            			}
            		}
            		void push_back(const T& x)
            		{
            			insert(end(), x);
            		}
            		void push_front(const T& x)
            		{
            			insert(begin(), x);
            		}
            		void pop_front()
            		{
            			erase(begin());
            		}
            		void pop_back()
            		{
            			erase(--end());
            		}
            		iterator insert(iterator pos, const T& x)
            		{
            			Node* cur = pos._node;
            			Node* newnode = new Node(x);
            			Node* prev = cur->_prev;
            			prev->_next = newnode;
            			newnode->_next = cur;
            			cur->_prev = newnode;
            			newnode->_prev = prev;
            			++_size;
            			return iterator(newnode);
            		}
            		iterator erase(iterator pos)
            		{
            			Node* cur = pos._node;
            			Node* next = cur->_next;
            			Node* prev = cur->_prev;
            			delete cur;
            			next->_prev = prev;
            			prev->_next = next;
            			--_size;
            			return iterator(next);
            		}
            		size_t size()
            		{
            			return _size;
            		}
            	private:
            		Node* _head;
            		size_t _size;
            	};
            }
            

            2.模板

            2.1非类型模板参数

            类型形参即:出现在模板参数列表中,跟在class或者typename之类的参数类型名称。

            非类型形参,就是用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当成常量来使用

            namespace ljh
            {
            	// 定义一个模板类型的静态数组
            	template
            	class array
            	{
            	public:
            	    T& operator[](size_t index)
            	    {
            	        return _array[index];
            	    }
            	
            		const T& operator[](size_t index)const
            		{
            		    return _array[index];
            		}
            		
            		size_t size()const
            		{
            		    return _size;
            		}
            		
            		bool empty()const
            		{
            		    return 0 == _size;
            		}
            	
            	private:
            	    T _array[N];
            	    size_t _size;
             	};
             }
            

            注意:

            1. 浮点数、类对象以及字符串是不允许作为非类型模板参数的。
            2. 非类型的模板参数必须在编译期就能确认结果

            2.2模板的特化

            2.2.1函数模板
            // 函数模板 -- 参数匹配
            template
            bool Less(T left, T right)
            {
            	return left 
微信扫一扫加客服

微信扫一扫加客服

点击启动AI问答
Draggable Icon