当前位置:   article > 正文

【C++11】理解基于范围的for循环,并且实现自定义的range循环_c++ for range

c++ for range

以前我们只能这样来遍历容器或者数组

vector<int> arr {1,2,3,4,5};
for(auto it =arr.begin(); it!=arr.end(); it++
{
}

或者是

for_each(auto it=arr.begin(); it!=arr.end(); do_something);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

这两种方法的弊端在于,都要写begin,和end
新的基于范围的for循环是这样的

for(auto v:arr)
{
}
  • 1
  • 2
  • 3

冒号前面的局部变量声明只要求能够支持容器类型的隐式转换。

这个for-range循环实际上只是C++的语法糖,它是下面代码的等价替换。

for(auto __begin = arr.begin(), __end = arr.end(); __begin!=__end; ++__begin
{}
  • 1
  • 2

也就是说只要for-range循环冒号后边的东西是个类,这个类只要实现begin(),end()方法,并且两个方法返回一个迭代器即可。迭代器正常要实现 !=重载,++重载 和 *重载。
现在我们要实现一个类似于Python的range循环
使用起来是这样

for(int i : range(2,5,2))
{
}
  • 1
  • 2
  • 3

这个range是个函数,它返回一个我们前面说的类

我们要实现迭代器,满足要求的类,和range函数
代码如下:

#pragma once
#include <iostream>
namespace detial_range
{
	template <typename T>
	class iterator
	{
	public:
		using value_type = T;
		using size_type = size_t;
	private:
		//Q:为什么迭代次是size_type,迭代步长和起始迭代值是value_type
		//A:因为cursor_代表要迭代的次数,其肯定是正整数,但是迭代步长和迭代值则是根据我们想要迭代什么数据类型来的。
		size_type			cursor_;	//迭代次数
		const value_type	step_;		//迭代步长
		value_type			value_;		//起始迭代值
	public:
		iterator(size_type cur_start, value_type begin_value, value_type step_value) :
			cursor_(cur_start), value_(begin_value), step_(step_value)
		{
			value_ += (step_ * cursor_);
		}

		value_type operator*() const { return value_; };

		bool operator!=(const iterator& rhs)
		{
			return (cursor_ != rhs.cursor_);
		}
		iterator& operator++(void)
		{
			value_ += step_;
			++cursor_;
			return (*this);
		}
	};

	//range类的具体实现
	template<typename T>
	class impl
	{
	public:
		using value_type = T;
		using reference = const value_type&;
		using const_reference = const value_type&;
		using iterator = const detial_range::iterator<value_type>;
		using const_iterator = const detial_range::iterator<value_type>;
		using size_type = typename iterator::size_type;

	private:
		const value_type begin_;
		const value_type end_;
		const value_type step_;
		const size_type max_conut_;//要迭代的次数

		//因为step_可能不是end_-begin_的最大公约数,所以需要调整迭代次数
		size_type get_adjust_conut(void) const
		{
			if (step_ > 0 && begin_ >= end_)
				throw std::logic_error("end_ 必须大于 begin_");
			else if (step_ < 0 && begin_ <= end_)
				throw std::logic_error("end_ 必须小于 begin_");

			size_type x = static_cast<size_type> ((end_ - begin_) / step_);
			if ((begin_ + step_ * x) != end_)++x;
			return x;
		}

	public:	//外部接口
		impl(value_type begin_value, value_type end_value, value_type step_value)
			:begin_(begin_value), end_(end_value), step_(step_value), max_conut_(get_adjust_conut())
		{}

		size_type size() const
		{
			return max_conut_;
		}

		const_iterator begin() const
		{
			return { 0,begin_, step_ };
		}

		const_iterator end() const
		{
			return const_iterator{ max_conut_, begin_, step_ };
		}
	};

	//range的外敷函数模板
	template<typename T>
	detial_range::impl<T> range(T end)
	{
		return { {},end,1 };
	}

	template<typename T>
	detial_range::impl<T> range(T begin, T end)
	{
		return { begin, end, 1 };
	}

	template <typename T, typename U>
	auto range(T begin, T end, U step) -> detial_range::impl<decltype (begin + step)>
	{
		using r_t = detial_range::impl<decltype(begin + step)>;
		return r_t{ begin ,end,step };
	}
};

void main()
{
	for (int i : detial_range::range(2, 5,2))
	{
		std::cout << "range(2,5) i:" << i << std::endl;
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号