来自: 深入应用c++代码优化与工程级应用
一:自定义迭代器类型,
重载运算符*(解引用), !=(用于循环结束判断),
定义3个成员变量, 用cursor来判断循环结束而不是value=it.value的原因是可能循环浮点数时有误差
templateclass Iterator { public: int cursor; //表示循环到第几下 T step; //表示步长 T value; //表示迭代器表示的值, 如begin为初始3, end为8 Iterator(int cursor_start, T begin_val, T step_val) : cursor(cursor_start), value(begin_val), step(step_val) { if (cursor != 0)//对于begin, cursor为0, 即value不变 { //对于end, cursor为最大循环次数,value=value+步长*次数 value += (step * cursor); } } T operator*() const //指针解引用 { return value; } //用cursor表示迭代器是否相等 bool operator!=(const Iterator &it) const { return cursor != it.cursor ; } Iterator &operator++() { value += step; //值+步长 ++cursor; //cursor前移 return *this; } };
二:自定义Range类
get_adjust_count()函数用于获取最大循环次数, 即(end-begin)/step+1,
若传入的参数错误会抛出异常
并实现 size(), begin(), end()这3个接口
begin(), end()返回的迭代器变量cursor分别用0, max_count初始化
templateclass Range { public: using iterator = Iterator ; T begin_; T end_; T step_; int max_count; int get_adjust_count() const { if (step_ > 0 && begin_ > end_ || step_ < 0 && begin_ < end_) { throw logic_error("error"); } int x = static_cast (end_ - begin_) / step_; if (begin_ + (step_ * x) != end_) ++x; return x; //获取最大循环次数 } Range(T begin_, T end_, T step_) : begin_(begin_), end_(end_), step_(step_), max_count(get_adjust_count()) {} [[nodiscard]] int size() const { return max_count; } iterator begin() { return {0, begin_, step_}; //cursor用0初始化 } iterator end() { return {max_count, begin_, step_};//cursor用max_count初始化 } };
三:最后是3个重载函数, 分别实现单参数, 双参数, 支持步长的三参数的循环
其中三参数的步长支持浮点数
//3个重载类型 templateRange range(T end) //[0,end) { return {{}, end, 1}; } template Range range(T begin, T end)//[begin,end) { return {begin, end, 1}; } //允许值或步长为浮点数, 取相加的值类型为返回类型 template auto range(T begin, T end, U step) -> Range { return Range (begin, end, step); }
测试
int main()
{
for (auto i : range(1,9,2))
{
cout<<( i )<
//输出->
1
3
5
7
-------
完整代码
#include
using namespace std;
template
class Iterator
{
public:
int cursor; //表示循环到第几下
T step; //表示步长
T value; //表示迭代器表示的值, 如begin为初始3, end为8
Iterator(int cursor_start, T begin_val, T step_val) :
cursor(cursor_start), value(begin_val), step(step_val)
{
if (cursor != 0)//对于begin, cursor为0, 即value不变
{
//对于end, cursor为最大循环次数,value=value+步长*次数
value += (step * cursor);
}
}
T operator*() const //指针解引用
{
return value;
}
//用cursor表示迭代器是否相等
bool operator!=(const Iterator &it) const
{
return cursor != it.cursor ;
}
Iterator &operator++()
{
value += step; //值+步长
++cursor; //cursor前移
return *this;
}
};
template
class Range
{
public:
using iterator = Iterator;
T begin_;
T end_;
T step_;
int max_count;
int get_adjust_count() const
{
if (step_ > 0 && begin_ > end_ || step_ < 0 && begin_ < end_)
{
throw logic_error("error");
}
int x = static_cast(end_ - begin_) / step_;
if (begin_ + (step_ * x) != end_) ++x;
return x; //获取最大循环次数
}
Range(T begin_, T end_, T step_) :
begin_(begin_), end_(end_), step_(step_), max_count(get_adjust_count())
{}
[[nodiscard]] int size() const
{
return max_count;
}
iterator begin()
{
return {0, begin_, step_}; //cursor用0初始化
}
iterator end()
{
return {max_count, begin_, step_};//cursor用max_count初始化
}
};
//3个重载类型
template
Range range(T end) //[0,end)
{
return {{}, end, 1};
}
template
Range range(T begin, T end)//[begin,end)
{
return {begin, end, 1};
}
//允许值或步长为浮点数, 取相加的值类型为返回类型
template
auto range(T begin, T end, U step) -> Range
{
return Range(begin, end, step);
}
int main()
{
for (auto i : range(1,9,2))
{
cout<<( i )<



