向量迭代器不可取消引用(尝试手动反转向量)

Vector Iterator not dereferencable (trying to manually reverse vector)

我正在尝试创建一个接受向量并简单地(手动)反转的函数。我知道 reverse() 的存在,但我 运行 进入了 "Vector iterator not dereferencable" 问题,出于教育目的,我想知道它的含义。我试着研究这个问题,有人(在这个论坛上)说 vect.end() 根据定义是不可取消引用的,但根据我的理解,使用 reverse_iterator 只是颠倒了结局,所以遵循逻辑; vect.rend 不应取消引用。

vector<int> reverseVector(vector<int>);

int main()
{
    vector<int> vec;

    for (int i = 0; i < 11; i++)
    {
        vec.push_back(i);
    }

    vec = reverseVector(vec);

    for (vector<int>::iterator it = vec.begin(); it != vec.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;

    return 0;
}

vector<int> reverseVector(vector<int> vect) 
{
    vector<int>::reverse_iterator ritr;
    for (ritr = vect.rbegin(); ritr != vect.rend(); ritr++)
    {
        vect.insert(vect.begin(), *ritr);
        vect.pop_back();
    }
    return vect;
}

您的问题与 rend() 的可解引用性或其他方面无关。您在迭代向量的同时修改向量,这会使迭代器无效。

为了回答您最初的问题,与前向迭代器相比,reverse_iterator 不仅仅是 "reversing the ends"。 rbegin()end() - 1rend()begin() - 1

如果向向量中添加一个元素,ritr 可能会无效,因此出现错误

Vector iterator not dereferencable.

因此,最好使用索引作为循环变量,或者更好地使用复制(临时)向量进行反向任务。

您正在从向量中删除元素(从后面弹出),这使反向迭代器无效。


您可以只遍历向量的 一半 并交换元素,例如:

void swap(int& a, int& b) {
    int tmp = a;
    a = b;
    b = tmp;
}

vector<int> reverseVector(vector<int> vect) {
    const size_t origin_size = vect.size();
    for(size_t i = 0; i < origin_size/2; ++i)
        swap(vect[i], vect[origin_size - 1 - i]);
    return vect;
}

两个 insert and pop_back 成员函数都修改向量并使迭代器无效。

作为设计问题的提示:在函数中始终使用 const-reference,除非您真的知道自己在做什么。所以你会避免踏入这样的陷阱。例如:

vector<int> reverseVector(const vector<int> &vect)

现在你不会有这个问题了,因为你不能修改vect。