python中的range函数表示一个连续的有序序列,range使用起来很方便,因为在定义时就隐含了初始化过程,因为只需要给begin()和end()或者仅仅一个end(),就能表示一个连续的序列。还可以指定序列产生的步长,如range(0,10,8)产生的序列为[0, 8], 默认的步长为1,range(3)表示的序列是[0,1,2]。range的遍历也很方便:

  for i in range(3):

  print i

  c++11中增加了一项新特性range-based for循环,其实这也不是什么新东西,在c#、java和python等语言中已经有了。这种循环方式非常简洁,它的内部其实是对传统的begin()/end()方式的遍历做了包装,算是一个循环的语法糖。用法很简单:

  //遍历vector

  std::vector v;

  for(auto i : v)

  {

  cout<

  }

  //以只读方式遍历map

  std::map map;

  for(const auto& item : map)

  {

  cout << item->first<second<

  }

  c++11的range-based for循环有意思的地方是他可以支持自定义类型的遍历,但是要求自定义类型满足三个条件:

  要实现begin()和end(),他们分别用来返回第一个或最后一个元素的迭代器 www.jx-jf.com

  提供迭代终止的方法;

  提供遍历range的方法 www.yzyedu.com

  满足这三个条件之后,我们自定义的类型就能支持range-based for循环了。

  再回到刚才提到的python的range(),它很好用,但是c++中目前还没有类似的东西,虽然标准库中有很多容器如vector、list、queue、map、初始化列表和array等等都已经支持了range-based for循环,但是他们使用起来还是不够方便,比如要生成一个有序序列时,需要专门去初始化,如果有一个类似于python range的东西就比较完美了。虽然c++11现在没有,但我们可以自己用c++11去实现一个类似的range,而且我还想让这个range比python的range更强大,让它不仅仅能支持整数还能支持浮点数,同时还能双向迭代,实现这个range还是比较简单的,看看具体实现吧:

  namespace Cosmos

  {

  template

  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

  auto Range(T begin, T end, V stepsize)->RangeImpl

  {

  return RangeImpl(begin, end, stepsize);

  }

  template

  RangeImpl Range(T begin, T end)

  {

  return RangeImpl(begin, end, 1);

  }

  template

  RangeImpl Range(T end)

  {

  return RangeImpl(T(), end, 1);

  }

  }

  再看看测试代码:

  void TestRange()

  {

  cout << "Range(15):";

  for (int i : Range(15)){

  cout << " " << i;

  }

  cout << endl;

  cout << "Range(2,6):";

  for (int i : Range(2, 6)){

  cout << " " << i;

  }

  cout << endl;

  cout << "Range(10.5, 15.5):";

  for (float i : Range(10.5, 15.5)){

  cout << " " << i;

  }

  cout << endl;

  cout << "Range(35,27,-1):";

  for (int i : Range(35, 27, -1)){

  cout << " " << i;

  }

  cout << endl;

  cout << "Range(2,8,0.5):";

  for (float i : Range(2, 8, 0.5)){

  cout << " " << i;

  }

  cout << endl;

  cout << "Range(8,7,-0.1):";

  for (auto i : Range(8, 7, -0.1)){

  cout << " " << i;

  }

  cout << endl;

  cout << "Range('a', 'z'):";

  for (auto i : Range('a', 'z'))

  {

  cout << " " << i;

  }

  cout << endl;

  }

  测试结果:

  可以看到这个range不仅仅会根据步长生成有序序列,还能支持浮点类型和char类型以及双向迭代,比python的range更强大。

用c++11打造类似于python的range的更多相关文章

  1. (原创)用c++11打造类似于python的range

    python中的range函数表示一个连续的有序序列,range使用起来很方便,因为在定义时就隐含了初始化过程,因为只需要给begin()和end()或者仅仅一个end(),就能表示一个连续的序列.还 ...

  2. python 中range numpy.arange 和 numpy.linspace 的区别

    1.返回值不同 range返回一个range对象,numpy.arange和numpy.linspace返回一个数组. 2.np.arange的步长可以为小数,但range的步长只能是整数. 与Pyt ...

  3. python中range()函数的用法

    python中range()函数可创建一个整数列表,一般用在for循环中. range()函数语法: range(start,stop[,step]) 参数说明: star: 计数从star开始.默认 ...

  4. python的range()函数使用方法

    python的range()函数使用非常方便.它能返回一系列连续添加的整数,它的工作方式类似于分片.能够生成一个列表对象. range函数大多数时常出如今for循环中.在for循环中可做为索引使用.事 ...

  5. A Neural Network in 11 lines of Python

    A Neural Network in 11 lines of Python A bare bones neural network implementation to describe the in ...

  6. 老司机带你用vagrant打造一站式python开发测试环境

      前言 作为一个学习和使用Python的老司机,好像应该经常总结一点东西的,让新司机尽快上路,少走弯路,然后大家一起愉快的玩耍. 今天,咱们就使用vagrant配合xshell打造一站式Python ...

  7. Python的range()函数用法

    Python的range()函数有三种用法,简单地说就是下图的三种用法: 运行结果如下:

  8. cplusplus 库 在线管理; 类似于 python的 pip install 、nodejs 的npm模块

    cplusplus 库 在线管理: 类似于 python的 pip install .nodejs 的npm模块 还有 apache 经常使用的 Apache Ivy 项目依赖管理工具/Maven 这 ...

  9. # Pycharm打造高效Python IDE

    Pycharm打造高效Python IDE 建议以scientific mode运行,在科学计算时,可以方便追踪变量变化,并且会提示函数的用法,比普通模式下的提示更加智能,一般在文件中引入了numpy ...

随机推荐

  1. 【宽搜】Vijos P1051 送给圣诞夜的极光

    题目链接: https://vijos.org/p/1051 题目大意: 给一张‘-’和‘#’的图,规定曼哈顿距离小于等于2的‘#’属于同一图案,求图案数.[曼哈顿距离:对于A(x1,y1)和B(x2 ...

  2. 【日语】アップデート(update)一吻定情OP

    ねぇ~気づいてる? nee ~ kizu iteru ?呐~注意到吗? 私はアップデートしているよwatashi ha appude^to shiteiruyo我期待更新 いつか届きますようにitsu ...

  3. Hadoop操作hdfs的命令【转载】

    本文系转载,原文地址被黑了,故无法贴出原始链接. Hadoop操作HDFS命令如下所示: hadoop fs 查看Hadoop HDFS支持的所有命令 hadoop fs –ls 列出目录及文件信息 ...

  4. hihocoder1236(北京网络赛J):scores 分块+bitset

    北京网络赛的题- -.当时没思路,听大神们说是分块+bitset,想了一下发现确实可做,就试了一下,T了好多次终于过了 题意: 初始有n个人,每个人有五种能力值,现在有q个查询,每次查询给五个数代表查 ...

  5. [Data Structure] 二叉搜索树(Binary Search Tree) - 笔记

    1. 二叉搜索树,可以用作字典,或者优先队列. 2. 根节点 root 是树结构里面唯一一个其父节点为空的节点. 3. 二叉树搜索树的属性: 假设 x 是二叉搜索树的一个节点.如果 y 是 x 左子树 ...

  6. Docker 初级实践

    Docker 应用 优势 与虚拟相比Docker更加轻量高效,更加方便移植.虚拟机提供的是完整的操作系统环境,包含了大量类似硬件驱动.虚拟处理器.网络接口等等并不需要的信息,也需要比较长时间的启动,同 ...

  7. 集群中几种session同步解决方案的比较

    1. 客户端cookie加密 .比较好的方法是自己采用cookie机制来实现一个session,在应用中使用此session实现. 问题:session中数据不能太多,最好只有个用户id. Sessi ...

  8. LSPCI具体解释分析

    一.PCI简单介绍     PCI是一种外设总线规范.我们先来看一下什么是总线:总线是一种传输信号的路径或信道.典型情况是,总线是连接于一个或多个导体的电气连线,总 线上连接的全部设备可在同一时间收到 ...

  9. HDU -1284钱币兑换

    这个是完全背包的基础题, 模拟换钱, 刚开始状态方程写错了,我直接写dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3], 然后想了想感觉太大了,不太对,后来看网上的代码 ...

  10. SQL 2008 清除数据库日志

    USE [master]GOALTER DATABASE DNName SET RECOVERY SIMPLE WITH NO_WAITGOALTER DATABASE DNName SET RECO ...