2010-03-31 121 views
3
list<int> foo; 
list<int> foo2; 
list<int>::iterator foo_end = foo.end(); 
list<int>::iterator foo2_end = foo2.end(); 

for (list<int>::iterator it = foo.begin(); it != foo2_end; ++foo) <- notice != comparison here 
{ 
    ... 

它这可以吗?它会正常工作。比较两端()迭代器

我倾向于认为这是实现相关的,任何人都知道,如果标准说这事?

回答

7

有关于此的一个缺陷(LWG defect 446)。缺陷报告询问是否有效比较引用不同容器元素的迭代器。

缺陷报告中的注释说明它确实是这样做的意图是未定义的,但没有明确说明它是未定义的。

,拟议的决议中加入以下的标准,明确指出它是未定义:

直接或间接评估任何比较函数或二进制结果 - 有两个迭代值作为参数操作从两个不同的范围r1和r2(包括它们的过去结束值)获得的不是一个共同范围的子范围是未定义的,除非另有明确说明。

编辑:该语言不包含在C++ 0x FCD中。这个问题实际上是通过N3066中的更改解决的; (§24.2.5/ 2):

前向迭代器的==的域是在同一个基础序列上的迭代器的域。

2

它是允许(即将编译)。
它将无法正常工作。

foo2_end点的foo2,不foo结束,所以当它到达的foo2结束,这将是永远的,因为你迭代foo你的迭代器将在foo和结束时开始启动。一旦it迭代到foo的末尾,您将收到seg-fault。

注:我认为你的意思是写++it而不是++foo

1

它会编译但会导致seg错误。迭代器是特定于对象的,并且比较来自不同对象的两个迭代器总是会产生不等式。因此,it != foo2_end表达式将始终评估为true,并且当it达到foo.end()并且您试图对其进行解引用时,程序将崩溃。

+0

这取决于迭代器的实现。一个简单而不是很好的实现一个列表迭代器可能是一个指向该节点的指针,其中null指向一个末尾(这是一个常见的习惯用法)[可能是某个操作需要一个指向列表的指针],相等被定义为所引用的节点地址的直接比较。标准中没有任何内容会导致实施不合规。 – 2010-03-31 08:20:13

+0

够公平的,尽管我认为商业级编译器会更聪明些。毕竟,使接口易于正确使用和难以正确使用是一个很好的共同目标。 :) – 2010-03-31 14:47:14

+0

@DavidRodríguez-dribeas“(一个)列表迭代器的实现可能是一个指向节点的指针,空指定一个结尾(这是一个常见的习惯用法)”你能否引用一个这样的std :: list实施? – curiousguy 2011-09-29 21:15:13