【问题标题】:For Random Access Iterator (vector iterator), are the iterators C++ style pointers?对于随机访问迭代器(向量迭代器),迭代器是 C++ 风格的指针吗?
【发布时间】:2020-04-23 03:12:56
【问题描述】:

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

    #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 也给了我一个(不同的)指针值。随机访问迭代器是指针中的指针吗?

【问题讨论】:

  • 我相信执行 iterEnd - iterBegin(如模板函数所示)是一个有效的操作,因为 iterEnd 和 iterBegin 都是 C++ 样式指针 -- 不,迭代器不是指针,但所有指针都是迭代器。向量迭代器的内部是实现定义的。一个著名的例子是 Visual C++,在 6.0 中,向量迭代器是简单的指针,但该编译器的后续版本将它们更改为 struct
  • 即使未指定确切的迭代器类型并且可能是也可能不是原始指针,但减法保证是有效的,因为这是所有Random Access Iterators 的要求。

标签: c++ iterator random-access


【解决方案1】:

对于 Random Access Iterator(向量迭代器),是 C++ 的迭代器 样式指针?

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

vector 迭代器的内部是实现定义的。 std::vector&lt;T&gt;::iterator 可能有 operator - 重载,因此它给出了指针减法的错觉。因此,如果您假设 vector 迭代器是简单指针,那么假设它们是简单指针编写代码将使用各种编译器中断,而对于其他编译器,它将成功编译。

其中一个著名的例子是 Visual C++,在 6.0 版本中,vector 迭代器是简单的指针,因此当时使用该编译器的许多作者会在假设 std::vector&lt;T&gt;::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&lt;T&gt;::iterator 不再是简单的T*,而是struct。对于 Visual C++ > 6.0 版,许多基于迭代器(错误)推理为简单指针的代码必须更改。

【讨论】:

    猜你喜欢
    • 2019-12-06
    • 2017-09-02
    • 2022-11-14
    • 2021-03-02
    • 2014-10-13
    • 2012-08-19
    • 1970-01-01
    • 2012-10-27
    • 2011-05-17
    相关资源
    最近更新 更多