比较来自不同容器的迭代器
比较不同容器的迭代器是否合法?
std::vector<int> foo; std::vector<int> bar;
expression式foo.begin() == bar.begin()
产生错误或未定义的行为?
(我正在写一个自定义的迭代器,并且在实现operator==
时候偶然发现了这个问题。)
如果您考虑C ++ 0x草稿:
§24.2.1
迭代器j被称为从迭代器可达我当且仅当有一个有限的序列的应用程序的expression式++ i,使i == j。 如果j从i可到达,则它们指的是相同序列的元素。
§24.2.5
前向迭代器的==域是相同基础序列上的迭代器的域。
鉴于RandomAccessIterator
必须满足由ForwardIterator
强加的所有要求,比较来自不同容器的迭代器是未定义的。
据我所知,未定义的行为。 在VS 2010中
/* * to disable iterator checking that complains that the iterators are incompatible (come from * different containers :-) */ #define _HAS_ITERATOR_DEBUGGING 0 std::vector<int> vec1, vec2; std::vector<int>::iterator it1 = vec1.begin(); std::vector<int>::iterator it2 = vec2.begin(); if (it1 == it2) { std::cout << "they are equal!!!"; }
在这种情况下,相等性testing返回true :-),因为容器是空的,迭代器的_Ptr成员都是nullptr。
谁知道你的实现可能会做不同的事情,testing会返回false :-)。
编辑:
请参阅C ++标准库“活动问题”列表 “446.不同容器之间的迭代器相等”。 也许有人可以检查标准,看看是否采纳了变化?
可能没有,因为它是在积极的问题清单,所以查尔斯贝利谁也回答这是正确的,这是不明确的行为。
所以我猜想不同的实现可能会有不同(至less在理论上),这只是一个问题。
事实上,在VS检查中的STL实现中启用了迭代器debugging,对于这种确切的情况(来自不同容器的迭代器)至less对我来说,应该尽可能地避免这种比较。
你不能直接比较不同容器的迭代器。 迭代器是一个使用容器的内部状态来遍历它的对象; 比较一个容器的内部到另一个容器根本没有意义。
但是,如果container.begin()
产生的迭代器可用,则可以通过从begin()
到当前迭代器值的对象的计数比较迭代器。 这是使用std::distance
:
int a = std::distance(containerA.begin(), iteratorA); int b = std::distance(containerB.begin(), iteratorB); if (a <comparison> b) { /* ... */ }
没有更多的背景,很难判断这是否能解决你的问题。 因人而异。
我相信这是不明确的行为(C ++ 03)。 std::vector
迭代器是随机访问迭代器, ==
的行为是在forward迭代器的需求中定义的。
==是等价关系
请注意,这是一个types的要求,所以必须适用于(在这种情况下)任何有效的(无法引用或以其他方式) std::vector::iterator
s对。 我相信这意味着==
必须给你一个true
/ false
答案,并不会导致UB。
– 如果a和b相等,则a和b都是可引用的,否则两者都不可引用。
相反,可解引用的迭代器不能与不可解引用的迭代器进行比较。
– 如果a和b都是可解引用的,则a == b当且仅当* a和* b是同一个对象。
请注意,对于两个不可解引用的迭代器,是否缺lessa == b
。 只要==
传递(如果a.end() == b.end()
和b.end() == c.end()
然后a.end() == c.end()
),反身( a.end() == a.end()
)和对称(如果a.end() == b.end()
然后b.end() == a.end()
)没关系如果一些,全部或没有end()
迭代器不同的容器比较相等。
还要注意,这与<
对比。 <
用b - a
定义,其中a
和b
都是随机访问迭代器。 执行b - a
先决条件是必须有一个Distance
值n
,使得a + n == b
需要a
和b
为迭代器到相同的范围。
不。如果这是合法的,这意味着指针不会是迭代器。
ISO / IEC 14882:2003(E)5.10.1
==(等于)和!=(不等于)运算符与关系运算符具有相同的语义限制,转换和结果types,除了它们的优先级较低和真值结果之外。 指向相同types的对象或函数(指针转换之后)的指针可以相等进行比较。 相同types的两个指针比较相等的当且仅当它们都是空的,都指向相同的函数,或者两者都代表相同的地址(3.9.2)。
XCode(3.2.3)的仿真结果:
#include <iostream> #include <vector> int main() { std::vector <int> a,aa; std::vector <float> b; if( a.begin() == aa.begin() ) std::cout << "\n a.begin() == aa.begin() \n" ; a.push_back(10) ; if( a.begin() != aa.begin() ) std::cout << "\n After push back a.begin() != aa.begin() \n" ; // Error if( a.begin() == b.begin() ) return 0; }
输出:
a.begin()== aa.begin()
推回a.begin()!= aa.begin()
我没有从标准的100%获得对input迭代器的要求,但是从那里(正向/双向/随机访问迭代器),对==域没有要求,所以它必须返回假 等式关系结果 。 你不能对不同容器的迭代器进行<或>或减法运算。
编辑:它不必返回false,它必须导致一个等价关系,这允许两个空容器的.begin()
比较相等(如另一个答案所示)。 如果迭代器是可取的, a == b => *a == *b
必须保持。 这仍然是不确定的行为。