(原创)用c++11打造类似于python的range
python中的range函数表示一个连续的有序序列,range使用起来很方便,因为在定义时就隐含了初始化过程,因为只需要给begin()和end()或者仅仅一个end(),就能表示一个连续的序列。还可以指定序列产生的步长,如range(0,10,8)产生的序列为[0, 8], 默认的步长为1,range(3)表示的序列是[0,1,2]。range的遍历也很方便:
for i in range():
print i
c++11中增加了一项新特性range-based for循环,其实这也不是什么新东西,在c#、java和python等语言中已经有了。这种循环方式非常简洁,它的内部其实是对传统的begin()/end()方式的遍历做了包装,算是一个循环的语法糖。用法很简单:
//遍历vector
std::vector<int> v;
for(auto i : v)
{
cout<<i<<endl;
} //以只读方式遍历map
std::map<string, int> map;
for(const auto& item : map)
{
cout << item->first<<item->second<<endl;
}
c++11的range-based for循环有意思的地方是他可以支持自定义类型的遍历,但是要求自定义类型满足三个条件:
- 要实现begin()和end(),他们分别用来返回第一个和最后一个元素的迭代器;
- 提供迭代终止的方法;
- 提供遍历range的方法;
满足这三个条件之后,我们自定义的类型就能支持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<typename value_t>
class RangeImpl
{
class Iterator;
public:
RangeImpl(value_t begin, value_t end, value_t step = ) :m_begin(begin), m_end(end), m_step(step)
{
if (step>&&m_begin >= m_end)
throw std::logic_error("end must greater than begin.");
else if (step< && 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(, *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, );
} template<typename T>
RangeImpl<T> Range(T end)
{
return RangeImpl<T>(T(), end, );
}
}
再看看测试代码:
void TestRange()
{
cout << "Range(15):";
for (int i : Range()){
cout << " " << i;
} cout << endl;
cout << "Range(2,6):";
for (int i : Range(, )){
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(, , -)){
cout << " " << i;
}
cout << endl;
cout << "Range(2,8,0.5):";
for (float i : Range(, , 0.5)){
cout << " " << i;
}
cout << endl;
cout << "Range(8,7,-0.1):";
for (auto i : Range(, , -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 boost技术交流群:296561497,欢迎大家来交流技术。
(原创)用c++11打造类似于python的range的更多相关文章
- 用c++11打造类似于python的range
python中的range函数表示一个连续的有序序列,range使用起来很方便,因为在定义时就隐含了初始化过程,因为只需要给begin()和end()或者仅仅一个end(),就能表示一个连续的序列.还 ...
- 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 ...
- 老司机带你用vagrant打造一站式python开发测试环境
前言 作为一个学习和使用Python的老司机,好像应该经常总结一点东西的,让新司机尽快上路,少走弯路,然后大家一起愉快的玩耍. 今天,咱们就使用vagrant配合xshell打造一站式Python ...
- cplusplus 库 在线管理; 类似于 python的 pip install 、nodejs 的npm模块
cplusplus 库 在线管理: 类似于 python的 pip install .nodejs 的npm模块 还有 apache 经常使用的 Apache Ivy 项目依赖管理工具/Maven 这 ...
- # Pycharm打造高效Python IDE
Pycharm打造高效Python IDE 建议以scientific mode运行,在科学计算时,可以方便追踪变量变化,并且会提示函数的用法,比普通模式下的提示更加智能,一般在文件中引入了numpy ...
- 第11.6节 Python正则表达式的字符串开头匹配模式及元字符“^”(插入符、脱字符)功能介绍
符号"^"为插入符,也称为脱字符,在Python中脱字符表示匹配字符串的开头,即字符串的开头满足匹配模式的要求.这个功能有点类似搜索函数match,只是这是通过搜索模式来指定,而m ...
- 第11.5节 Python正则表达式搜索任意字符匹配及元字符“.”(点)功能介绍
在re模块中,任意字符匹配使用"."(点)来表示, 在默认模式下,点匹配除了换行的任意字符.如果指定了搜索标记re.DOTALL ,它将匹配包括换行符的任意字符.关于搜索标记的含义 ...
- 第11.13节 Python正则表达式的转义符”\”功能介绍
为了支持特殊元字符在特定场景下能表示自身而不会被当成元字符进行匹配出来,可以通过字符集或转义符表示方法来表示,字符集表示方法前面在<第11.4节 Python正则表达式搜索字符集匹配功能及元字符 ...
- 第11.7节 Python正则表达式的字符串结尾匹配模式及元字符“$”功能介绍
符号"$"表示匹配字符串的结尾,即字符串的结尾满足匹配模式的要求. 在 MULTILINE 模式(搜索标记中包含re.MULTILINE,关于搜索标记的含义请见<第11.2节 ...
随机推荐
- ACE的源码划分
前几篇文章也提到过,ACE的所有源文件和头文件都杂乱堆在了ACE_wrappers/ace目录下.这样的代码组织方式给学习ACE带来了很大的困难,很多朋友在看到ace目录下庞大的代码的时候,几乎就失去 ...
- (原)tensorflow中函数执行完毕,显存不自动释放
转载请注明出处: http://www.cnblogs.com/darkknightzh/p/7608916.html 参考网址: https://stackoverflow.com/question ...
- 致Play Framework开发者们的一封信
2012/04/06 导读:3月中旬,Play Framework 2.0 正式版发布了.2.0 版本的主要新特性:内置对 Java 和 Scala 的支持.完全异步编程模型.侧重于类型安全.强大的 ...
- quine
发鸠之山,其上多柘木,有鸟焉,其状如乌,文首,白喙,赤足,名曰:"精卫",其鸣自詨(音同"笑").是炎帝之少女,名曰女娃.女娃游于东海,溺而不返,故为精卫,常衔 ...
- [转]webMethods公司简介
原文链接 webMethods公司简介 webMethods,Inc.(美国纳斯达克股市上市代号:WEBM)为著名业务整合软件供应商之一.公司于1996年创立,总部位于美国佛吉尼亚州(Virginia ...
- 基本的RAID介绍
RAID是一个我们经常能见到的名词.但却因为很少能在实际环境中体验,所以很难对其原理 能有很清楚的认识和掌握.本文将对RAID技术进行介绍和总结,以期能尽量阐明其概念. RAID全称为独立磁盘冗余阵列 ...
- 信号之sigsetjmp和siglongjmp函数(转)
在信号处理程序中经常调用longjmp函数以返回到程序的主循环中,而不是从该处理程序返回. 但是,调用longjmp有一个问题.当捕捉到一个信号时,进入信号捕捉函数,此时当前信号被自动地加到进程的信号 ...
- Python学习笔记(四)——编码和字符串
一.编码 1.编码类别: (1)ASCII码:127个字母被编码到计算机里,也就是大小写英文字母.数字和一些符号 (2)GB2312码:中国制定的用于加入中文汉字的编码 (3)Unicode:防止由于 ...
- 【Oracle】Oracle基本数据类型总结
ORACLE基本数据类型(亦叫内置数据类型 built-in datatypes)可以按类型分为:字符串类型.数字类型.日期类型.LOB类型.LONG RAW& RAW类型.ROWID &am ...
- atom介绍
在公司微信群,看到activate-power-mode插件的效果,很绚丽,才知道github自己出了一个自己的编辑器atom 官网地址 https://atom.io 官网看了下,atom编辑器的特 ...