栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

c++新特性:让基于范围的for循环支持自定义类型

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

c++新特性:让基于范围的for循环支持自定义类型

来自: 深入应用c++代码优化与工程级应用

一:自定义迭代器类型,

重载运算符*(解引用), !=(用于循环结束判断),

定义3个成员变量, 用cursor来判断循环结束而不是value=it.value的原因是可能循环浮点数时有误差

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;
    }
};

二:自定义Range类

get_adjust_count()函数用于获取最大循环次数, 即(end-begin)/step+1,

若传入的参数错误会抛出异常

并实现 size(), begin(), end()这3个接口

begin(), end()返回的迭代器变量cursor分别用0, max_count初始化

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个重载函数, 分别实现单参数, 双参数, 支持步长的三参数的循环

其中三参数的步长支持浮点数

//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  )< 
//输出->
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  )< 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1038855.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号