vector的iterator的错误使用

本文讨论了C++标准库中vector迭代器的一个特殊问题,即通常不能对临时迭代器进行增量和减量操作。这是因为vector迭代器通常实现为普通指针,而对临时值的指针修改是不允许的。尽管此问题在编译时就能发现,避免意外行为,但它可能浪费开发者的时间。对于字符串迭代器,也存在相同问题,因为它们通常也是字符指针。使用deque、list、set和map等其他容器则不会遇到这个问题,因为它们的迭代器不能实现为普通指针。为确保代码可移植,建议避免直接使用++coll.begin()这样的写法。示例代码展示了如何使用iter_swap算法函数,但当容器为vector时,程序通常无法正常工作,因为vector的迭代器需要随机访问迭代器支持。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文如下:(摘自<<c++ standard library>>)

 

 

7.2.6 The Increment and Decrement Problem of Vector Iterators

The use of the increment and decrement operators of iterators includes a strange problem. In general, you can increment and decrement temporary iterators. However, for vectors and strings, you typically can't. Consider the following vector example:

					
   std::vector<int> coll;
   ...
   //sort, starting with the second element
   // - NONPORTABLE version 
   if (coll.size() > 1) {
       coll.sort (++coll.begin(), coll.end());
   }

				

Typically, the compilation of sort() fails. However, if you use, for example, a deque rather than a vector, it will compile. It might compile even with vectors, depending on the implementation of class vector.

The reason for this strange problem lies in the fact that vector iterators are typically implemented as ordinary pointers. And for all fundamental data types, such as pointers, you are not allowed to modify temporary values. For structures and classes, however, it is allowed. Thus, if the iterator is implemented as an ordinary pointer, the compilation fails; if implemented as a class, it succeeds. It always works with deques, lists, sets, and maps because you can't implement iterators as ordinary pointers for them. But for vectors, whether it works depends on the implementation. Usually, ordinary pointers are used. But if, for example, you use a "safe version" of the STL, the iterators are implemented as classes. To make your code portable you should not code as the previous example, using vectors. Instead, you should use an auxiliary object:

					
   std::vector<int> coll;
   ...
   //sort, starting with the second element
   // - PORTABLE version
   if (coll.size() > 1) {
       std::vector<int>::iterator beg = coll.begin();
       coll.sort (++beg, coll.end()); 
   }

				

The problem is not as bad as it sounds. You can't get unexpected behavior because it is detected at compile time. But it is tricky enough to spend time solving it. This problem also applies to strings. String iterators are usually also implemented as ordinary character pointers, although this is not required.

 

 

意思是说vector里面的iterator实际上是个指针类型。所以,coll.begin()返回的是容器存储的首个元素的地址,也就返回了一个指针的值,所以不能对其进行++coll.begin()操作。而通过std::vector<int>::iterator beg另外定义一个变量后,就可以对其进行++beg操作了。

 

如果不是vector,而是list,由于list里面的iterator是一个类,所以可以用list mylist; ++mylist.being()操作。但是sort支持的是randomaccess iterator,所以,不能在sort里使用list的iterator作为参数。下面用iter_swap算法函数演示:

 

 

 #include <iostream>
   #include <list>
   #include <algorithm>
   #include "print.hpp"
   using namespace std;


   int main() 
   {
       list<int> coll;


       //insert elements from 1 to 9
       for (int i=1; i<=9; ++i) {
           coll.push_back(i); 
       }


       PRINT_ELEMENTS(coll);


       //swap first and second value
       iter_swap (coll.begin(), ++coll.begin());


       PRINT_ELEMENTS(coll);


       //swap first and last value
       iter_swap (coll.begin(), --coll.end());

       PRINT_ELEMENTS(coll);
   }

				

The output of the program is as follows:

					
   1 2 3 4 5 6 7 8 9
   2 1 3 4 5 6 7 8 9
   9 1 3 4 5 6 7 8 2

 

 

Note that this program normally does not work if you use a vector as a container. This is because ++coll.begin() and --coll.end() yield temporary pointers (see Section 7.2.6, for details regarding this problem).

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值