3

这个问题在我看来更像是出于学术兴趣而不是实际用例:

STL 关联容器,即 [multi]set 和 [multi]map,包含重载方法,例如:

// for std::map
void erase ( iterator position );
size_type erase ( const key_type& x );

// for std::set
iterator  erase (const_iterator position);
size_type erase (const value_type& val);

我的问题:如果key_type,分别怎么办。value_typeiteratorconst_iterator

我知道将迭代器存储在容器中是危险的并且可能没用。但是实际的 STL 实现会如何表现呢?行为是否已定义?

4

3 回答 3

10

问题是迭代器类型会有所不同。他们永远不可能相同。原因:在这种情况下必须满足以下等式:

map<K, V>::iterator == K
map<K, V>::const_iterator == K

但是,这些等式不能成立(你看到递归了吗)?请记住,迭代器类型取决于容器类型,包括其模板参数。

所以在下面的例子中,键类型和迭代器类型是不同的,就像你试图让它们相等一样:

map<map<int,int>::iterator, int> i;

实际上,由于上​​述原因,我无法实例化一个键等于其迭代器类型的映射。因此,重载的erase方法如下所示:

void erase ( map<map<int,int>::iterator, int>::iterator position );
size_type erase ( const map<int,int>::iterator & x );

所以重载永远不会模棱两可。如果类型相同,那将是模棱两可的,请参见:http: //ideone.com/fMdwru。但是,只要您使用该方法,编译器就会抱怨。所以,假设我们可以在这里引入歧义,只要我们想使用该方法,它就会困扰我们。我的意思是,我们仍然可以实例化地图类型(如果它存在的话)。

于 2013-01-08T13:23:19.363 回答
6

将迭代器存储在容器中并没有本质上的错误。需要注意的两个主要问题是:

  1. 您可能需要知道每个迭代器指的是哪个容器;
  2. 您必须知道原始容器上的哪些操作会使哪些迭代器无效。

我的问题:如果key_type,分别怎么办。value_typeiteratorconst_iterator

如果所有四种类型都指代相同的容器类型,则答案是根据定义它们不可能相同。

于 2013-01-08T13:20:51.483 回答
0

这样做没有错,也不是没用。:)

请记住,迭代器基本上只是广义指针。如有疑问,请假设它们的行为类似于指针。您可以创建指针容器,因此也可以创建迭代器容器。

当然,您必须记住,如果您修改容器,指向该容器的迭代器可能会失效(取决于执行的操作和容器的类型),但这仅意味着您必须知道存储的迭代器仍然存在有效的。

于 2013-01-08T13:26:35.427 回答