auto关键字实现简易的数值范围迭代器

比如需要遍历数值范围[5,10),直观的方法是:

for (int i = 5; i < 10; i++) {
    .....
}

c++11的auto关键字,可以不指定数据类型,如下:

for (auto i = 5; i < 10; i++) {
    .....
}

c++11的auto关键字,还可以遍历容器,如下:

std::vector<int> v = {5,6,7,8,9};
for (auto i: v) {
    .....
}

c++11的auto的区间迭代功能,功能就是大幅减少不必要代码开发。需要这个容器能够:

1、有begin()和end()方法,返回容器头尾的迭代器;

2、支持"*"(取值)、"++"(迭代器前移)、"!="(判断迭代器是否相同)这三个运算符重载


STL的vector、set、map、unordered_map、unordered_set等容器都支持。

那么也没有办法也实现一个,能够快速简单遍历任意数值区间的容器呢,比如遍历[5,10)的数值范围

同样是实现上面的1和2里的5个方法,即begin、end、*、++、!=,这5个方法;

下面是思路:

1、需要实现两个类型,分别是"数值范围容器类"和"数值范围容器的迭代器类",前者命名为Range,后者命名为Iterator,

     循环体就如下:

     for (auto i: Range(5, 10)) {

    ..... //i 依次为5、6、7、8、9
}

     Range类支持begin()和end()方法,它们都返回两个迭代器Iterator分别是头尾数据对应的迭代器

     Range在迭代过程中,每次返回一个迭代器Iterator

2、迭代器Iterator支持*、++、!=这3个方法

     *:获取迭代器当前对应的值

     ++: 迭代器前移

     !=: 判断两个迭代器是否相同

3、如何设计Iterator:

     简单就是一个区间,没有逻辑的关联,不妨每个数值对应一种迭代器

     *: 就对应这个数值

     ++: 数值加1,再获取这个数值

     !=: 两个迭代器获取各自的数值,然后判断是否相等

     对于!=,因为数值区间的数值不会重复,所以就可以简单的这样处理

class Iterator {                                                                           
        int64_t value_;                                                                        
                                                                                               
        int64_t GetValue () const {                                                            
            return value_;                                                                     
        }                                                                                      
                                                                                               
    public:                                                                                    
        Iterator (uint64_t value): value_(value) {}                                            
        bool operator!= (const Iterator &other) const {                                        
            return GetValue() != other.GetValue();                                             
        }                                                                                      
                                                                                               
        uint64_t operator* () const {                                                          
            return GetValue();                                                                 
        }                                                                                      
                                                                                               
        const Iterator &operator++ () {                                                        
            ++value_;                                                                          
            return *this;                                                                      
        }                                                                                      
    };

     Range类,接受数值区间的头和尾,进而的begin()和end(),返回两个对应的Iterator迭代器对象

     

class Range {                                                                              
        uint64_t begin_;                                                                       
        uint64_t end_;                                                                         

    public:
        Range(uint64_t begin, uint64_t end): begin_(begin), end_(end) {}
        Iterator begin() {
            return Iterator(begin_);
        }

        Iterator end() {
            return Iterator(end_);
        }
    };

     这样在遍历过程中,首先由begin()获取到第一个迭代器Iterator对象,然后它不断调用"++"前移,直到发现"!="end()的迭代器对象不再成立,为止:

     测试代码如下:

     for (auto i: common::Range(5, 10)) {

    std::cout << i << std::endl;//依次输出5、6、7、8、9
}

     总结:

     1、支持begin()、end()、*、++、!=五个方法容器,可以使用auto循环迭代

     2、原则上,这样的容器,应包括容器类和容器迭代器类,

                       容器类应支持begin()和end()两方法,返回头尾对应的迭代器对象;

                       容器迭代器类,应支持*、++、!=这三个方法,分别对应所需的取值、前移、判断位置是否相同;

     3、循环首先由容器类的begin()方法获取到头对象对应的迭代器,并不断调用"*"取值、"++"前移,直到调用"!="发现迭代到end()方法获取到的尾对象对应的迭代器为止;




  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值