对于随机访问迭代器(矢量迭代器),迭代器C++样式指针吗?

For Random Access Iterator (vector iterator), are the iterators C++ style pointers?

本文关键字:迭代器 样式 C++ 指针 访问 于随机      更新时间:2023-10-16

我有以下代码来随机化列表容器中的元素:

#include <vector>
#include <list>
#include <iterator>
#include <algorithm>
#include <iostream>
using namespace std;
template<class RandomAccesIterator>
void randomize(RandomAccesIterator iterBegin, RandomAccesIterator iterEnd)
{
while (iterBegin != iterEnd)
{
iter_swap(iterBegin, iterBegin + rand() % (iterEnd - iterBegin));
++iterBegin;
}
}

然后稍后在 main((:

int main()
{
//container used as to apply algorithm to.
list<int> List = {34,77,16,2,35,76,18,2};
//randomize example.
cout << "calling randomize on sorted vector: " << endl;
List.sort();
vector<int> temp(List.begin(), List.end());
cout << "before randomize: " << endl;
for (vector<int>::iterator it = temp.begin(); it != temp.end(); it++)
{
cout << *it << " ";
}
cout << endl;
randomize(temp.begin(),temp.end());
cout << "after randomize: " << endl;
for (vector<int>::iterator it = temp.begin(); it != temp.end(); it++)
{
cout << *it << " ";
}
cout << endl<<endl;
return 0;
}

我有几个问题:

  1. 我相信执行 iterEnd - iterBegin(如模板函数所示(是一个有效的操作,因为 iterEnd 和 iterBegin 都是C++样式指针。 减去这些指针会得到它们之间的距离。我说的对吗?

  2. 我在即时窗口中尝试了以下内容:

iterEnd
{-33686019}
[ptr]: 0x00ba4f78 {-33686019}
[Raw View]: {...}

这意味着 iterEnd 是一个指针,其值为 0x00ba4f78,它指向 -33686019 的垃圾值。我相信我在这里是对的?

因此,迭代器是一个指针,用于随机访问迭代器。是否适用于所有迭代器类型(输入/输出迭代器、前向迭代器、双向迭代器(?如果这些迭代器不是C++样式指针,那么它们是什么?

  1. 我还在即时窗口中尝试了以下内容:
&iterEnd
0x006ff368 {-33686019}
[ptr]: 0x00ba4f78 {-33686019}
[Raw View]: 0x006ff368 {...}
&&iterEnd
expected an expression

为什么 &iterEnd 给我一个地址?它应该给我消息"期望一个表达式",就像 &&iterEnd 所做的那样。

  1. 随机访问迭代器是如何实现的? - 我问是因为 iterEnd 给了我一个指针值,并且 iterEnd 也给了我一个(不同的(指针值。随机访问迭代器是指针中的指针吗?

对于随机访问迭代器(矢量迭代器(,迭代器C++ 样式指针?

简短的回答 - 这取决于编译器。

vector迭代器的内部是实现定义的。std::vector<T>::iterator可能operator -过载,因此它给人一种指针减法的错觉。 因此,如果您假设vector迭代器是简单指针,则编写假设它们是简单指针的代码将使用各种编译器中断,而对于其他编译器,它将成功编译。

一个著名的案例是Visual C++,在6.0版本中,vector迭代器是简单的指针,因此当时使用该编译器的许多作者都会在编写代码时假设std::vector<T>::iterator只是一个T*。 由于矢量迭代器是作为指针实现的,因此代码编译成功并正常工作

一个例子是这样的:

#include <vector>
void foo(char *c)
{
}
int main()
{
std::vector<char> vc;
foo(vc.begin());
}

没有编译错误,因为vc.begin()是一个简单的char *

然后是Visual C++的后续版本,过去在6.0下成功编译的代码现在被破坏了。std::vector<T>::iterator不再是一个简单的T*,而是一个struct。 对于 Visual C++> 6.0 版,必须更改许多基于迭代器作为简单指针的(错误(推理的代码。