![](/img/trans.png)
[英]For C++ Random Access Iterator (vector iterator), how is the difference between iterators calculated?
[英]For Random Access Iterator (vector iterator), are the iterators C++ style pointers?
我有以下代碼來隨機化列表容器中的元素:
#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;
}
我有幾個問題:
我相信執行 iterEnd - iterBegin(如模板函數中所示)是一個有效的操作,因為 iterEnd 和 iterBegin 都是 C++ 風格的指針。 減去這些指針給出它們之間的距離。 我對么?
我在即時窗口中嘗試了以下操作:
iterEnd
{-33686019}
[ptr]: 0x00ba4f78 {-33686019}
[Raw View]: {...}
表示iterEnd是一個指針,值為0x00ba4f78,指向垃圾值-33686019。 我相信我在這里是正確的嗎?
因此,迭代器是一個指針,用於隨機訪問迭代器。 是否適用於所有迭代器類型(輸入/輸出迭代器、前向迭代器、雙向迭代器)? 如果這些迭代器不是 C++ 風格的指針,那么那些是什么?
&iterEnd
0x006ff368 {-33686019}
[ptr]: 0x00ba4f78 {-33686019}
[Raw View]: 0x006ff368 {...}
&&iterEnd
expected an expression
為什么 &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 版進行更改。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.