使用C++实现Range序列生成器

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

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

c 复制代码
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 序列生成器轻松生成不同类型的序列,无需编写复杂的循环结构,从而简化了代码编写过程。每个循环迭代并输出相应的序列元素,使读者能够更轻松地处理不同类型的数据。

c 复制代码
#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;
}
相关推荐
莫名其妙小饼干8 分钟前
网上球鞋竞拍系统|Java|SSM|VUE| 前后端分离
java·开发语言·maven·mssql
十年一梦实验室17 分钟前
【C++】sophus : sim_details.hpp 实现了矩阵函数 W、其导数,以及其逆 (十七)
开发语言·c++·线性代数·矩阵
taoyong00121 分钟前
代码随想录算法训练营第十一天-239.滑动窗口最大值
c++·算法
最爱番茄味26 分钟前
Python实例之函数基础打卡篇
开发语言·python
这是我5827 分钟前
C++打小怪游戏
c++·其他·游戏·visual studio·小怪·大型·怪物
fpcc35 分钟前
跟我学c++中级篇——C++中的缓存利用
c++·缓存
呆萌很1 小时前
C++ 集合 list 使用
c++
Oneforlove_twoforjob1 小时前
【Java基础面试题033】Java泛型的作用是什么?
java·开发语言
engchina1 小时前
如何在 Python 中忽略烦人的警告?
开发语言·人工智能·python
向宇it1 小时前
【从零开始入门unity游戏开发之——C#篇24】C#面向对象继承——万物之父(object)、装箱和拆箱、sealed 密封类
java·开发语言·unity·c#·游戏引擎