使用C++实现Range序列生成器的示例代码

 更新时间:2023年11月05日 08:21:28   作者:lyshark  
在C++编程中,经常需要迭代一系列数字或其他可迭代对象,本文将使用C++来实现一个简单的Range封装,文中的示例代码讲解详细,感兴趣的可以了解下

在C++编程中,经常需要迭代一系列数字或其他可迭代对象。通常,这需要编写复杂的循环结构,但有一种精妙的方法可以使这一过程变得更加简单和可读。如果你使用过Python语言那么一定对Range语句非常的数据,我们可以使用C++来实现一个简单的Range封装,如下代码定义了一个名为Range的命名空间,其中包含一个RangeImpl类和相关的函数,用于生成指定范围内的数值序列。这序列生成器支持指定开始值、结束值和可选步长,确保生成的序列满足指定的条件。此代码简化了迭代数值序列的过程,提高了代码的可读性和可维护性,适用于处理不同数据类型的序列。

首先读者需要新建一个Range.hpp头文件,并包含这个生成器代码。

namespace Range
{
  template<typename value_t>
  class RangeImpl
  {
    class Iterator;
  public:
    RangeImpl(value_t begin, value_t end, value_t step = 1) :m_begin(begin), m_end(end), m_step(step)
    {
      if (step>0 && m_begin >= m_end)
        throw std::logic_error("end must greater than begin.");
      else if (step<0 && m_begin <= m_end)
        throw std::logic_error("end must less than begin.");

      m_step_end = (m_end - m_begin) / m_step;
      if (m_begin + m_step_end*m_step != m_end)
      {
        m_step_end++;
      }
    }

    Iterator begin()
    {
      return Iterator(0, *this);
    }

    Iterator end()
    {
      return Iterator(m_step_end, *this);
    }

    value_t operator[](int s)
    {
      return m_begin + s*m_step;
    }

    int size()
    {
      return m_step_end;
    }

  private:
    value_t m_begin;
    value_t m_end;
    value_t m_step;
    int m_step_end;

    class Iterator
    {
    public:
      Iterator(int start, RangeImpl& range) : m_current_step(start), m_range(range)
      {
        m_current_value = m_range.m_begin + m_current_step*m_range.m_step;
      }

      value_t operator*() { return m_current_value; }

      const Iterator* operator++()
      {
        m_current_value += m_range.m_step;
        m_current_step++;
        return this;
      }

      bool operator==(const Iterator& other)
      {
        return m_current_step == other.m_current_step;
      }

      bool operator!=(const Iterator& other)
      {
        return m_current_step != other.m_current_step;
      }

      const Iterator* operator--()
      {
        m_current_value -= m_range.m_step;
        m_current_step--;
        return this;
      }

    private:
      value_t m_current_value;
      int m_current_step;
      RangeImpl& m_range;
    };
  };

  template<typename T, typename V>
  auto Range(T begin, T end, V stepsize)->RangeImpl<decltype(begin + end + stepsize)>
  {
    return RangeImpl<decltype(begin + end + stepsize)>(begin, end, stepsize);
  }

  template<typename T>
  RangeImpl<T> Range(T begin, T end)
  {
    return RangeImpl<T>(begin, end, 1);
  }

  template<typename T>
  RangeImpl<T> Range(T end)
  {
    return RangeImpl<T>(T(), end, 1);
  }
}

当需要使用这个特殊的语句时,只需要直接引入到项目中,如下代码所示展示了如何在不同的情况下创建和迭代不同类型的数值序列,包括整数、浮点数和字符序列。以下是对每个循环的简要描述:

  • 第一个循环使用Range::Range(15)创建一个整数序列,范围从0到14。
  • 第二个循环使用Range::Range(2, 6)创建一个整数序列,范围从2到5。
  • 第三个循环使用Range::Range(10.5, 15.5)创建一个浮点数序列,范围从10.5到15.5。
  • 第四个循环使用Range::Range(35, 27, -1)创建一个递减的整数序列,范围从35到27。
  • 第五个循环使用Range::Range(2, 8, 0.5)创建一个浮点数序列,范围从2到8,步长为0.5。
  • 第六个循环使用Range::Range(8, 7, -0.1)创建一个浮点数序列,范围从8到7,步长为-0.1。
  • 最后一个循循环使用Range::Range('a', 'z')创建一个字符序列,范围从'a'到'z'。

这个示例程序演示了如何使用 Range 序列生成器轻松生成不同类型的序列,无需编写复杂的循环结构,从而简化了代码编写过程。每个循环迭代并输出相应的序列元素,使读者能够更轻松地处理不同类型的数据。

#include <iostream>
#include "Range.hpp"

using namespace std;

int main(int argc, char* argv[])
{
  for (int i : Range::Range(15))
  {
    std::cout << i << std::endl;
  }

  for (int i : Range::Range(2, 6))
  {
    std::cout << i << std::endl;
  }

  for (float i : Range::Range(10.5, 15.5))
  {
    std::cout << i << std::endl;
  }

  for (int i : Range::Range(35, 27, -1))
  {
    std::cout << i << std::endl;
  }

  for (float i : Range::Range(2, 8, 0.5))
  {
    std::cout << i << std::endl;
  }

  for (auto i : Range::Range(8, 7, -0.1))
  {
    std::cout << i << std::endl;
  }

  for (auto i : Range::Range('a', 'z'))
  {
    std::cout << i << std::endl;
  }
  
  std::system("pause");
  return 0;
}

到此这篇关于使用C++实现Range序列生成器的示例代码的文章就介绍到这了,更多相关C++序列生成器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++ Protobuf实现接口参数自动校验详解

    C++ Protobuf实现接口参数自动校验详解

    用C++做业务发开的同学是否还在不厌其烦的编写大量if-else模块来做接口参数校验呢?今天,我们就模拟Java里面通过注解实现参数校验的方式来针对C++ protobuf接口实现一个更加方便、快捷的参数校验自动工具,希望对大家有所帮助
    2023-04-04
  • C语言实现输入两个数字将其按从小到大输出的方法

    C语言实现输入两个数字将其按从小到大输出的方法

    这篇文章主要介绍了C语言实现输入两个数字将其按从小到大输出的方法,本文通过代码讲解的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • C++ Primer中&、*符号的多重定义与int *p和int* p的区别讲解

    C++ Primer中&、*符号的多重定义与int *p和int* p的区别讲解

    今天小编就为大家分享一篇关于C++Primer中&、*符号的多重定义与int *p和int* p的区别讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-04-04
  • C语言实现QQ窗口抖动功能

    C语言实现QQ窗口抖动功能

    这篇文章主要为大家详细介绍了C语言实现QQ窗口抖动功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-11-11
  • C语言超详细讲解指针的概念与使用

    C语言超详细讲解指针的概念与使用

    本文主要讲解C语言中指针和字符串的关系以及指针和数组的关系,在看本文之前大家可以先看看博主之前的C语言基础篇,先对C语言指针先有个基础的了解,有助于对本文章有更深一步的了解
    2022-05-05
  • C++ STL之list双向链表容器方式

    C++ STL之list双向链表容器方式

    这篇文章主要介绍了C++ STL之list双向链表容器方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-04-04
  • Qt添加MSVC2017编译器的实现方法

    Qt添加MSVC2017编译器的实现方法

    Qt添加MSVC2017编译器是开发者在Windows平台上进行Qt应用程序开发的重要步骤,本文详细介绍了如何为Qt配置MSVC2017编译器的具体步骤,感兴趣的可以了解一下
    2023-09-09
  • C++中文件操作基础详解

    C++中文件操作基础详解

    这篇文章主要为大家详细介绍了C++中的一些文件操作基础详解,文中的示例代码讲解详细,对我们学习C++有一定帮助,需要的可以参考一下
    2022-06-06
  • MFC对话框中实现走马灯效果

    MFC对话框中实现走马灯效果

    这篇文章主要为大家详细介绍了MFC对话框中实现走马灯效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-05-05
  • C++文件读取的4种情况汇总

    C++文件读取的4种情况汇总

    前几天要用到C++读取文本文件,就学习了一下几种不同的读取方法,下面这篇文章主要给大家介绍了关于C++文件读取的4种情况,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-01-01

最新评论