1

首先:如果有人能想到更简洁的表达方式,我很乐意更新标题中的问题。

情况如下:

我有一个向量作为班级成员。使用以下内容从向量中提取元素后:

inline int currentToken()
{
    /* __it is of type std::vector <int>::iterator */

    return (__it < __tokens.begin()) ? Syntax::OUT_OF_RANGE_BEGIN :
           (__it > __tokens.end())   ? Syntax::OUT_OF_RANGE_END :
           *__it;
}

返回的整数与预期的完全一样(在本例中为 65,它应该是)。

然而,现在事情变得棘手了。当遇到这个特定的标记时,它会引发一个新的事件链,并且需要丢弃向量中以前的标记。

首先,我调用类的“saveLocation”成员函数,它是一个内联快捷方式:

__saved_it = __it;

然后,我调用 'truncateHead' 成员函数,这是错误发生的地方。在代码之前,我想指出,以上都没有以任何方式改变向量,所以绝对没有理由重新分配向量的内存。

__it = __tokens.erase(__tokens.begin(), __saved_it+1); //segfault

一些调试显示不知何故__it大于__tokens.end(),即使它仍然大于__begin 并且按预期取消引用到数字“65”。

它怎么不在 和 之间的范围__tokens.begin()__tokens.end()

事实上,这种情况在上述saveLocation方法中已经存在。

记住currentToken()紧随其后的是saveLocation(), 并且如果迭代器已经超出范围currentToken会返回整数表示,我很困惑。OUT_OF_RANGE_END

彻底而彻底。

4

2 回答 2

4

tokens.end()返回一个结束迭代器。也就是说,它已经在范围之外。

比较一个迭代器是否大于>结束迭代器的 ( ) 是没有意义的,因为迭代器的范围仅从begin()to end()。由于同样的原因,检查一个迭代器是否小于返回的迭代器也是没有意义的begin()

这意味着无法检查迭代器是否为OUT_OF_RANGE_BEGINor OUT_OF_RANGE_END。您只能检查它是否在有效范围内。

可以检查迭代器是否大于或等于 ( >=) 返回的迭代器begin()

当您检查是否__it超过最后一个元素时,您应该评估迭代器是否不等于tokens.end()

例如,您应该检查类似

return (__it >= __tokens.begin()
     && __it != __tokens.end()) ? *__it : Syntax::OUT_OF_RANGE;

这还要求您不要将迭代器递增到容器之后的结束迭代器。访问一个迭代器指向的内存,该迭代器已经增加超过end()-iterator 将导致未定义的行为。

于 2013-07-18T01:54:21.803 回答
2

迭代器比较仅对指向同一范围的迭代器有效。测试一个迭代器是容器<的迭代器还是容器的结束迭代器没有任何意义。begin>

于 2013-07-18T15:18:17.197 回答