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; }; }
注意:
2.2模板的特化
2.2.1函数模板
// 函数模板 -- 参数匹配 template bool Less(T left, T right) { return left