编写自定义迭代器 - 如果你在数组末尾怎么办?

时间:2010-04-24 23:19:46

标签: c++

我正在为Matrix类编写一个自定义迭代器,我想实现increment方法,当迭代器递增时会调用它:

void MatrixIterator::increment()
{
    // go to the next element
}

假设迭代器已经增加了太多次,现在指向超过矩阵的末尾(即超过了一个过去的结束点)。这种情况的最佳做法是什么?我是否应该使用断言来捕获它,或者我应该只是说用户有责任跟踪迭代器指向的位置并且这不属于我的业务?

5 个答案:

答案 0 :(得分:4)

你可以断言,但一般来说你不需要做任何事情。 C ++迭代器不应该捕获错误。例如。 STL迭代器不这样做。

答案 1 :(得分:1)

您根本不需要处理它。如果迭代器已经递增超过container::end(),则会调用未定义的行为。即使它崩溃了,根据STL语义,这仍然是合法的。

编辑:换句话说:
[S]我是否应该说用户有责任跟踪迭代器所指向的位置,这不关我的事情?
是。

答案 2 :(得分:1)

你没有做任何事情,但它可以真的有助于在那里断言。任何人使用你的代码将迭代器增加到最后都有一个bug。如果你什么都不做,你可能会调用未定义的行为,这可能包括程序似乎正常工作,但在罕见和困难的情况下崩溃。那太讨厌了。如果断言,使用代码的开发人员可以更容易地发现问题。

请注意,大多数主要编译器都提供了已检查(或调试)版本的STL,其中包括在增加迭代器结束时断言,使用无效的迭代器等。这非常有用,因为您获得了调试在这些情况下断言而不是未定义的行为,并且它都是在发布版本中编译的。虽然您可以不在乎,并且STL作者可以不在乎,但将这些诊断信息放入其中会非常有帮助。

答案 3 :(得分:0)

你确定你的矩阵类实际上必须有iterator吗?据我所知,编码矩阵时的最佳做法是重载operator (),以便它可以作为双索引器并在此阶段保留。

但是,如果你愿意,那就保持原样/放assert。一般来说,第二种变体不是必需的,但这就是它在STL中的表现。我很确定你在MSVS中看到断言iterator not dereferencable ......

编辑看起来就像是我开始玩的地方。当迭代器克服了结束并且not dereferencable断言位于另一个地方时,STL中没有断言......

答案 4 :(得分:0)

通常,当C ++迭代器超出容器的末尾时,迭代器的值将设置为等于end()返回的值。

所以

iterator++;
if ( iterator == container.end() )
{
   // break from loop
}

从它的外观来看,结束可以是你想要的任何价值。