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更强大。
相关文章
- 06-28第三百六十八节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)用Django实现搜索的自动补全功能
- 06-28四十七 Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)用Django实现搜索的自动补全功能
- 06-28(原创)用c++11打造好用的variant(更新)
- 06-28用python破解有道翻译,打造属于自己的翻译软件!
- 06-28用Tkinter打造自己的Python IDE开发工具(2)实现Python代码执行并输出信息
- 06-28(原创)用c++11打造类似于python的range
- 06-28用c++11打造类似于python的range