如果你只想迭代一个范围并再次循环,你可以走非常疯狂的路线,只需定义一个“容器”(或范围,在boost术语中),提供迭代器(技术上它们更像是几乎迭代器),这样你就可以表达出你想做的事情。
for(auto i : down_and_up(3)) ::std::cout << i << "\n";
例如应该打印
3
2
1
0
1
2
遗憾的是,标准库中对于这种类型的支持不多,但boost提供了boost::iterator_range
、boost::counting_iterator
和boost::join
,与std::reverse_iterator
共同使用,可以提供down_and_up
。如果你不完全滥用它,编写一个自己的迭代器相当简单(尽管冗长):
struct down_and_up
{
size_t from;
down_and_up(size_t const from) : from(from) { }
struct iterator : public ::std::iterator<::std::forward_iterator_tag, size_t> {
size_t cur;
bool down;
iterator(size_t cur, bool down) : cur(cur), down(down) { }
size_t operator*() const { return cur; }
iterator& operator++()
{
if(down)
{
--cur;
if(0 == cur) down = false;
}
else ++cur;
return *this;
}
friend bool operator==(iterator const& lhs, iterator const& rhs) { return lhs.down == rhs.down && lhs.cur == rhs.cur; }
friend bool operator!=(iterator const& lhs, iterator const& rhs) { return lhs.down != rhs.down || lhs.cur != rhs.cur; }
};
iterator begin() const { return iterator{ from, true }; }
iterator end() const { return iterator{ from, false }; }
};
注意:如果您愿意,可以轻松地扩展它的容器功能,比如一个
value_type
成员类型定义,但是上述定义已经足够了。
附注:为您的娱乐,这是boost的方式:
boost::iterator_range<boost::counting_iterator<size_t>> up(boost::counting_iterator<size_t>(0), boost::counting_iterator<size_t>(3));
boost::iterator_range<std::reverse_iterator<boost::counting_iterator<size_t>>> down(
std::reverse_iterator<boost::counting_iterator<size_t>>(boost::counting_iterator<size_t>(4)),
std::reverse_iterator<boost::counting_iterator<size_t>>(boost::counting_iterator<size_t>(1)));
for(auto i : boost::join(down, up)) ::std::cout << i << "\n";
i
值范围是错误的。您应该使用for (int i = 255; i >= 0; i--)
。 - R Sahu