对于集合类型,所有的end()迭代器是否相等?

6

在C++中给定一个特定的STL集合,对于相同模板化的所有实例,是否end()值是等价的?换句话说,以下代码是否适用于所有STL容器和情况(而不仅仅是std::map)?

std::map<Key, Value> foo(int seed);

std::map<Key, Value> instance1 = foo(1);
std::map<Key, Value> instance2 = foo(2);
std::map<Key, Value>::iterator itr = instance1.begin();
std::map<Key, Value>::iterator endItr = instance2.end(); // Comes from other collection!

for (; itr != endItr; ++itr) {
  // Do something on each key value pair...
}

可能会在特定的实现中发挥作用,但您只能针对使用默认构造函数创建“end”迭代器的类型(例如std::istream_iterator)进行计数。即使在这些情况下,也没有直接保证。 - Jerry Coffin
2
如果这个能运行,那你就算是倒霉了。这显然是你代码里的一个bug。我以为MSVC会检测到这种类型的迭代器误用,但也许只有被检查过的迭代器才会被检测到。 - Steve Townsend
@SteveTownsend:我认为这在MSVC上是保证可行的,因为它们实现了SCARY iterators - Jesse Good
@Jesse:不完全正确。SCARY迭代器允许您混合使用迭代器类型,而不考虑比较器/分配器类型,因此std::map<K,V>::iteratorstd::map<K,V, custom_compare>::iterator是相同的类型,但这并不意味着两个映射的结束迭代器具有相同的值。 - Dave S
@DaveS:啊,对了,SCARY 迭代器只涉及类型等价性而不是值等价性。感谢你的纠正。 - Jesse Good
3个回答

7
不行,因为STL容器和迭代器有特定要求:
23.2.1 通用容器要求 [container.requirements.general]
6 begin() 返回指向容器中第一个元素的迭代器。end() 返回一个past-the-end值(超过末尾的值)的迭代器。如果容器为空,则begin() == end();
24.2.1 全局要求 [iterator.requirements.general]
6 如果只有存在一种从i到j的固定的应用++i序列使得i == j,则称迭代器j可以从迭代器i到达。如果j可以从i到达,则它们引用同一序列的元素。
对于空容器而言,begin()和end()的相等意味着它们需要是同一容器对象的一部分,因此end()不能是容器类的静态成员。请注意,除了前向迭代器之外,在end()上应用operator--将无法与静态的end()迭代器解决。

你怎么知道那不起作用?如果std::map::end返回一个对于某个特定专业的所有映射都相同的对象,会怎样呢? - mfontanini
4
我们可不可以把未定义行为简单理解为“不起作用”?每次都要详细解释吗?请帮我翻译这段话。 - Benjamin Lindley
@BenjaminLindley 嗯,这是一个合法的问题,最终标准会详细说明。 - TemplateRex
1
顺便说一句,我认为你的静态 end() 想法面临的最大障碍是 operator--。如果它不知道所属的容器对象,那它应该去哪里呢? - Benjamin Lindley
@Benjamin Lindley 的观点很好,但这并不适用于 forward_list 或任何其他仅具有前向迭代器的用户自定义基于节点的容器。 - TemplateRex
显示剩余4条评论

2
通常情况下,不是可移植的。它可能在某些平台上偶然起作用。
有一些终止迭代器可以用于不同的范围,例如默认构造的istream_iterator,可以被重新使用。
ifstream a("foo.txt");
ifstream b("bar.txt");
istream_iterator<string> end;
istream_iterator<string> ia( a);
istream_iterator<string> ib( b);
// from here on both [ia, end> and [ib, end> are valid ranges.

0

现在自己试试:

#include <map>
#include <iostream>
using namespace std;
map<int,int> m1;
map<int,int> m2;

int main() {
  cout<<(m1.end() == m2.end())<<endl;
}

http://ideone.com/o18DtQ

output:

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接