在这种情况下,您不会迭代容器的内容。相反,您正在迭代容器的有效迭代器。
因此,一种方法是明确表示。
创建一个所述迭代器的序列,其end
元素是end
该序列的最后一个迭代器的过去一个。
因为我疯了,如果我必须解决这个问题,我会写一个函数iterators
,当给定一个sequence
(一个for( : )
循环工作的对象)时,它会产生一个sequence
迭代器而不是底层类型的序列。
它需要一个enum
参数来说明它是否包含end
迭代器。它将默认为独占。
你会这样使用它:
for( auto it : iterators( sequence, include_end ) ) {
// code
}
编写该函数的工作并非微不足道,但它会使使用点的循环看起来非常干净。
以理智的方式编写此代码将涉及使用boost
迭代器库。稍微不那么理智将涉及重新实现boost
迭代器库的一部分,无论是逐字还是通过手工编写更糟,然后使用它。写它而不复制它的精神或文字boost
将是一个坏主意。
template<typename iterator>
struct iterator_iterator: boost::iterator_facade<
iterator_iterator<iterator>, iterator,
typename std::iterator_traits<iterator>::iterator_category,
iterator const&,
typename std::iterator_traits<iterator>::difference_type
>:{
// sufficient state:
iterator current;
iterator src_end;
bool past_end_iterator;
// now, implement the core operations. Note that
// random advance has to be careful, because we cannot advance
// current beyond src_end. Note we should implement every one
// of the methods in the requirements (including advance), but
// only the ones that the underlying iterator's category requires
// should be called and hence instantiated.
iterator dereference() const { return current; }
bool equal( iterator_iterator<iterator> other ) const {
if (past_end_iterator || other.past_end_iterator)
return past_end_iterator && other.past_end_iterator;
return current == other.current;
}
void increment() {
if (current == src_end) {
past_end_iterator = true;
} else {
++current;
}
}
void decrement() {
if (past_end_iterator) {
past_end_iterator = false;
} else {
--current;
}
}
void advance( std::ptrdiff_t n ) {
if (n==0)
return;
if (n==1) {
increment();
} else if (n==-1) {
decrement();
}
if ((n>0) && ( current+(n-1) == src_end ) {
current = src_end;
past_end_iterator = true;
} else if ((n<0) && past_end_iterator) {
past_end_iterator = false;
++n;
current = src_end + n;
} else {
current += n;
}
}
typename std::iterator_traits<iterator>::difference_type distance_to(
iterator_iterator<iterator> other
) const {
if (past_end_iterator || other.past_end_iterator) {
if (past_end_iterator && other.past_end_iterator) {
return 0;
using std::distance;
auto retval = distance( current, other.current );
if (past_end_iterator)
return retval-1;
else
return retval+1;
}
}
};
或类似的东西。(未编译,只是编写)您将使用一对开始/结束迭代器,并创建一对开始/结束迭代器或开始/过去结束迭代器迭代器,具体取决于您是否要包含结束迭代器在迭代器的迭代中。
我怀疑上面的 CRTP 是堆栈溢出代码中迭代器一词的最高有用使用密度之一:在 5 行代码中使用了 13 次迭代器。