簡體   English   中英

對於隨機訪問迭代器(向量迭代器),迭代器是 C++ 風格的指針嗎?

[英]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;
}

我有幾個問題:

  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 版進行更改。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM