reverse_iterator反向迭代器(萃取版)

14 篇文章 0 订阅

目录

1.返向迭代器结构

2.反向迭代器原理

3.反向迭代器实现重载

4. 反向迭代器模拟实现(没有萃取)

5. 迭代器隐式类型转化

6. 反向迭代器萃取

7. 反向迭代器模拟实现(萃取版)


1.返向迭代器结构


2.反向迭代器原理

能用上反向迭代器, 说明容器支持双向读取,双向迭代器

那么是不是所以的满足这个条件的迭代器本身也有满足反向迭代器的潜质

所以反向迭代器是一个面向迭代器类的封装,范性编程

反向迭代器的模板参数就是这个迭代器的类型


3.反向迭代器实现重载

1. 构造函数:        使用迭代器来构造

Iterator(node* x)
    :_it(x)
{}
Reverse_Iterator(iteartor x)
    :rit(x)
{}
reverse_iterator rend()
{ 
    return iterator(_head->_next);
}

这里iterator内部就是一个指针,可以用指针构造一个iterator对象

iterator对象又可以作为reverse_iterator的参数去构建

在第三个里函数的返回值是reverse_iterator类型,而返回的对象是一个iterator对象

这中间发生了隐式类型转化,当自定义类型的构造函数只有一个参数就可以进行隐式类型转换

2. operator++         其实是类成员--iterator

self operator++()
{
    --rit;
    return *this;
}

3. operator--         其实是类成员++iterator

self operator--()
{
    ++rit;
    return *this;
}

4. operator*         其实是类成员先找到前一个再--返回解引用后的内容

Ref operator*()
{
    iteartor tmp = rit;
    return *(--tmp);
}

5.operator->         其实是类成员先找到前一个再--返回取地址后的内容

Ptr operator->()
{
    return &(operator*());
}

6. operator!=        

bool operator!=(const self& x) const
{
    return rit != x.rit;
}

4. 反向迭代器模拟实现(没有萃取)

#pragma once

namespace kele
{
	template<class iteartor, class Ref, class Ptr>
	struct Reverse_Iterator
	{
		typedef Reverse_Iterator<iteartor, Ref, Ptr> self;
		iteartor rit;

		Reverse_Iterator(iteartor x)
			:rit(x)
		{}

		Ref operator*()
		{
			iteartor tmp = rit;
			return *(--tmp);
		}

		Ptr operator->()
		{
			return &(operator*());
		}

		self operator++()
		{
			--rit;
			return *this;
		}

		self operator++(int)
		{
			self tmp = *this;
			--rit;
			return tmp;
		}

		self operator--()
		{
			++rit;
			return *this;
		}

		self operator--(int)
		{
			self tmp = *this;
			++rit;
			return tmp;
		}

		bool operator!=(const self& x) const
		{
			return rit != x.rit;
		}

		bool operator==(const self& x) const
		{
			return rit == x.rit;
		}
	};
}

5. 迭代器隐式类型转化

自己实现的list可能会出现下面这种情况

int main()
{    
    int arr[] = { 1,7,4,6,9,8,0 };
	kele::list<int> t(arr, arr + 7);

	kele::list<int>::const_iterator rit = t.begin();
	while (rit != t.end())
	{
		cout << *rit << " ";
		++rit;
	}
	cout << endl;
    return 0;
}

error C2440: “初始化”: 无法从“kele::__list_iterator<T,T &,T *>”转换为“kele::__list_iterator<T,const T &,const T *>”

对于自定义类型一般编译器不会进行隐式类型转换,但是如果在自定义类型的中存在一个只有一个参数的构造函数,就会发生隐式类型转换


6. 反向迭代器萃取

萃取,个人理解,从模板参数反向推导模板所对应的类内的类型

从下面的例子:

template <class T>
struct MyIter {
    typedef T value_type;
    T* ptr;

    MyIter(T* p) {
        ptr = p;
    }

    T& operator*() {
        return *ptr;
    }
};

template <class I>
typename I::value_type
func(I ite) {	// typename I::value_type 为返回值类型
    return *ite;
}

int main()
{
    MyIter<int> ite(new int(1231));
    cout << func(ite);
    return 0;
}

此处  typename  的作用是告诉编译器这是一个类型,因为 I 是一个模板参数,在它被具现化之前编译器对它一无所知,也就是说编译器不知道 I::value_type 是个类型或是成员函数等等。

例子来自:http://t.csdnimg.cn/oCoKA

反向迭代器传参其实只需要一个,另外两个类型都可以萃取推导出来

对应反向迭代器的类模板参数只需要iterator

直接萃取

直接萃取对于自定义类型的iterator且类内部存在 value_type 等类型可以实现

但是对于 Iterator 是原生指针 这种就不行,内置类型不能萃取,因为不存在 value_type 类型

还有一种办法 构建迭代器萃取器

这里利用 类模版的偏特化 针对模板参数更进一步的条件限制所设计出来的一个特化版本

C++ 模板icon-default.png?t=N7T8http://t.csdnimg.cn/4nmel反向迭代器的隐式类型转化

这里有没有可能发生 const_reverse_iterator 转换成 reverse_iterator 权限放大?

有可能,但是不是完全可能

反向迭代器的构造在这一句        :rit(x.rit)        实现 

问题就转换了,变成了 const_iterator 构造成 iterator

如果底层迭代器实现没有问题,反向迭代器就不会有问题


7. 反向迭代器模拟实现(萃取版)

#pragma once

namespace kele
{
	template <class Iterator>
	struct iterator_traits {
		typedef typename Iterator::value_type        value_type;
		typedef typename Iterator::pointer           pointer;
		typedef typename Iterator::reference         reference;
	};

	template <class T>
	struct iterator_traits<T*> {
		typedef T                          value_type;
		typedef T*						   pointer;
		typedef T&						   reference;
	};

	template <class T>
	struct iterator_traits<const T*> {
		typedef T                          value_type;
		typedef const T*				   pointer;
		typedef const T&				   reference;
	};

	template<class Iteartor>
	struct Reverse_Iterator
	{
		typedef typename iterator_traits<Iteartor>::value_type value_type;
		typedef typename iterator_traits<Iteartor>::reference reference;
		typedef typename iterator_traits<Iteartor>::pointer pointer;

		typedef Reverse_Iterator<Iteartor> self;

		Iteartor rit;

		Reverse_Iterator(Iteartor x)
			:rit(x)
		{}

		template<class iter>
		Reverse_Iterator(const Reverse_Iterator<iter>& x)
			:rit(x.rit)
		{}

		reference operator*()
		{
			Iteartor tmp = rit;
			return *(--tmp);
		}

		pointer operator->()
		{
			return &(operator*());
		}

		self operator++()
		{
			--rit;
			return *this;
		}

		self operator++(int)
		{
			self tmp = *this;
			--rit;
			return tmp;
		}

		self operator--()
		{
			++rit;
			return *this;
		}

		self operator--(int)
		{
			self tmp = *this;
			++rit;
			return tmp;
		}

		bool operator!=(const self& x) const
		{
			return rit != x.rit;
		}

		bool operator==(const self& x) const
		{
			return rit == x.rit;
		}
	};
}

  • 26
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值