2011-08-31 30 views
4

短的问题之前:是使用下面的代码不安全的其他编译器比我(的mingw32),或者是有效使用?的std ::列表<>:元素l.begin()

list<int> l; 
/* add elements */ 
list<int>::iterator i = l.begin(); 
i--; 
i++; 
cout << *i << endl; 

...或者换句话说:是i定义为指向在此之后l.begin()

回答

12

是,代码是不安全的。一旦您尝试移动begin()之前,您已导致未定义的行为。试图移动“回来”可能无法正常工作。

+0

是'--list.end()不这样做'也UB? –

+0

只要列表不为空,就没问题。你会在列表中的最后一个“真实”元素。 ++ list.end()将是未定义的。 –

+2

@SethCarnegie:'list.end()'不是一个左值,所以它的格式不正确。当且仅当列表不为空时,才可以递减指向“list.end()”的迭代器。 –

2

一个std ::列表,经由链表指针横穿它的内容,所以指针运算不用于计算正确的位置。 .begin()之前的位置将没有数据,并且不应提供任何有效的遍历机制。

容器,如性病::载体具有随机访问迭代器,并会在幕后使用指针运算,所以他们可能会给出正确的结果(没问题),但它仍然是一个坏主意。

因此,它不应该工作,它的不确定,即使它不以某种方式工作:)

+0

链接列表和指针是一个完整的实现细节。 –

+0

像std :: vector <>'这样的容器的迭代器仍然遵循标准中有关双向+迭代器的规则,它具体地说这是未定义的行为。 – ildjarn

+0

是的,我同意这两个评论 - 它的未定义和链接列表是一个实现细节。但它可能不适用于他的情况,因为它几乎可以肯定是一个链表,而biderectional迭代器很可能使用向量的指针运算,所以应该允许运动通过末端。虽然这是违反标准和坏的,但我认为他们会很好的考虑。如果我添加了一些混淆,应用:( –

相关问题