简体   繁体   English

迭代器的STL容器如何表现?

[英]How does an STL container of iterators behave?

This question appeared to me rather out of academic interest than an actual use-case: 这个问题在我看来是出于学术兴趣,而不是实际的用例:

The STL associative containers, namely [multi]set and [multi]map, contain overloaded methods like: STL关联容器,即[多]集和[多]映射,包含重载方法,如:

// 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);

My question: What if key_type , resp. 我的问题: 如果key_type ,resp。 value_type is iterator or const_iterator ? value_typeiterator还是const_iterator

I am aware that it is dangerous and probably useless to store iterators in a container. 我知道将迭代器存储在容器中是危险的并且可能没用。 But how would an actual STL implementation behave? 但是实际的STL实现会如何表现? Is the behaviour even defined? 行为甚至定义了吗?

The thing is that the iterator types would be different. 问题是迭代器类型会有所不同。 It can't ever happen that they are the same. 不可能它们是相同的。 The reason: The following equalities had to hold in this case: 原因是:在这种情况下必须遵循以下平等:

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

However, these equalities can't hold (do you see the recursion)? 但是,这些等式无法保持(你看到递归)吗? Remember that iterator types depend on the container type, including its template parameters. 请记住,迭代器类型取决于容器类型,包括其模板参数。

So in the following example, the key type and the iterator type are different, as much as you try to make them equal: 因此,在下面的示例中,键类型和迭代器类型是不同的,只要您尝试使它们相等:

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

Indeed, because of the reason from above, I can't instantiate a map which key equals its iterator type. 实际上,由于上​​面的原因,我无法实例化一个键等于其迭代器类型的映射。 Thus, the overloaded erase methods look like this: 因此,重载的erase方法如下所示:

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

So the overload will never be ambiguous. 因此,重载永远不会是模棱两可的。 If the types were equal, it'd be ambiguous, see this: http://ideone.com/fMdwru . 如果类型相同,那就不明确了,请看: http//ideone.com/fMdwru However, the compiler only complains as long as you are using the method. 但是,只要您使用该方法,编译器就会抱怨。 So, let's say we could introduce ambiguity here, it only bothers us as long as we want to use the method. 所以,假设我们可以在这里引入歧义,只要我们想要使用该方法,它只会困扰我们。 I mean, we still could instantiate the map type (if it existed). 我的意思是,我们仍然可以实例化地图类型(如果它存在)。

There's nothing inherently wrong with storing iterators in a container. 将迭代器存储在容器中没有任何内在错误。 Two main issues to be aware of are: 需要注意的两个主要问题是:

  1. you may need to know which container each iterator refers to; 您可能需要知道每个迭代器引用的容器;
  2. you have to know which operations on the original container would invalidate which iterators. 您必须知道原始容器上的哪些操作将使哪些迭代器无效。

My question: What if key_type , resp. 我的问题:如果key_type ,resp。 value_type is iterator or const_iterator ? value_typeiterator还是const_iterator

If all four types refer to the same container type, the answer is that they can't be the same, by definition. 如果所有四种类型都引用相同的容器类型,则答案是根据定义它们不能相同。

There's nothing wrong with doing this, and it's not useless either. 这样做没有错,也没用。 :) :)

Remeber that iterators are basically just generalized pointers. 记住迭代器基本上只是泛化指针。 When in doubt, assume that they behave like pointers. 如有疑问,请假设它们的行为类似于指针。 You can create containers of pointers, so you can also create containers of iterators. 您可以创建指针容器,因此您也可以创建迭代器容器。

Of course, you have to keep in mind that if you modify a container, iterators pointing to that container may be invalidated (depending on the operation performed and the type of container), but that just means you have to know that the stored iterators stay valid. 当然,您必须记住,如果您修改容器,指向该容器的迭代器可能会失效(取决于执行的操作和容器的类型),但这只是意味着您必须知道存储的迭代器保持不变有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM