在C ++中从container.end()中减去是否安全?

时间:2015-10-01 23:04:39

标签: c++ stl iterator language-lawyer

也就是说,假设container不为空,我可以安全地执行此操作:

std::vector<int> container;
container.push_back( 0xFACE8D );
auto last = container.end() - 1;

和此:

编辑:在-1替换--

std::list<int> container;
container.insert( 0xFACE8D );
auto last = container.end();
--last;

再次为任意非空容器?

编辑:让我澄清一下这个问题。

有时完全合法的代码行为不正确。问题是:假设上面的代码编译,这样做是否安全?

对于普通的C风格数组应该是安全的,因为相应的迭代器只是指针。但对于更复杂的容器是否安全?

假设使用像这样的迭代器实现列表:

class MyListIterator {
    MyListIterator *prev, *next;
    MyListIterator * operator--() { return prev; }
    ...
};

class MyList {
    MyListIterator *end() { return NULL; }
    ...
}; 

然后尝试递减container::end(),尽管在句法上完全合法,但会导致段错误。

但我希望stl容器比这更聪明。因此,关于上述stl::list代码行为的保证的问题,如果有的话。

2 个答案:

答案 0 :(得分:7)

std::vector会返回random-access iterators,所以是的,这对vector来说是安全的。

std::list返回bidirectional iterators。它们可以递增(++)和递减(--),但不允许任意算术(+-)或相对比较({{1} },>)。使用<并不安全。

您可以在双向迭代器上使用std::advance来提前或后退任意数量。在C ++ 11中,您可以使用std::prev代替list

答案 1 :(得分:3)

C ++标准说std::vector<T>::iterator是指向过去元素的随机访问迭代器。因此,您可以安全地使用-+运算符。

std::vector不同,std::list<T>::iterator双向迭代器,仅支持--++运算符。