使用反向迭代器插入std::list会更改原始反向迭代程序的值

Inserting to std::list using reverse iterator changes the value of the original reverse iterator

本文关键字:原始 迭代 程序 list 迭代器 插入 std      更新时间:2023-10-16

我在网上搜索了很多,但找不到问题的答案。

我正在使用std::列表的reverse_iterator将一个值插入到该列表中。虽然插入发生在预期的适当位置,但我注意到用于插入的原始reverse_iterator的值发生了变化。同样,一个完全无关的反向器的值也发生了变化。我已经能够在一个简单的例子中重现这一点

#include <iostream>
#include <list>
#include <string>
int main()
{
    // Creating a list of values 1, 2, 4, 5
    std::list<int> myList;
    myList.push_back(1);
    myList.push_back(2);
    myList.push_back(4);
    myList.push_back(5);
    // Changing it to 1, 2, 3, 4, 5 by inserting 3
    std::list<int>::reverse_iterator revIter = myList.rbegin();
    while(2 != *revIter)
    {
        std::cout << *revIter << "t";
        ++revIter;
    }
    std::cout << "n" << "Reverse iterator now points to " << *revIter;
    // Creating a copy of the reverse Iter before inserting.
    std::list<int>::reverse_iterator newRevIter = revIter;
    myList.insert(revIter.base(), 3);
    // Checking the values of revIter and newRevIter 
    std::cout << "n" << "Reverse Iterator now points to " << *revIter; // UNEXPECTED RESULT HERE
    std::cout << "n" << "New Reverse Iterator now points to " << *newRevIter; // UNEXPRECTED RESULT HERE
    std::cout << "n" << "Printing final list:" << "n";
    for(std::list<int>::iterator iter = myList.begin(); myList.end() != iter; ++iter)
    {
        std::cout << *iter << "t"; // Results are fine
    }
    return 0;
}

结果

5    4
Reverse iterator now points to 2
Reverse iterator now points to 3
New Reverse iterator now points to 3
Printing final list:
1    2    3    4    5

这是预期的行为吗。如果是这样,如何使用反向迭代器向列表中插入项(或者在这方面它是无用的)?

我会避免使用反向迭代器(通常情况下,尤其是对于顺序横向之外的任何东西)。前向迭代器和反向迭代器的工作方式不同,在将前向迭代器放入列表的情况下,迭代器跟踪您通过operator*访问的节点,但在相反的情况下迭代器会跟踪列表中的下一个元素。取消引用反向迭代器的行为获得迭代器引用的节点的前置节点,并从中提取值。图形化地(f是正向迭代器,r是反向迭代器)

  f
1 2 4
    r

前向迭代器f和反向迭代器r在解引用时都会产生2,但它们跟踪的节点不同。当您使用r插入时,您将插入2到4之间,但底层迭代器仍然指向持有4:的节点

  f
1 2 3 4
      r

现在,如果您取消引用r,则应用与上面相同的过程。将获得当前节点的前置节点,并打印值,但现在4的前置节点为3,这就是您获得的值。

这是预期的行为吗。如果是这样,如何使用反向迭代器向列表中插入项(或者在这方面它是无用的)?

是的,这是预期行为。如何使用反向迭代器向列表中插入项?了解它是如何工作的。

插入后的不变量是std::reverse_iterator<>::base(),而不是std::reverse_iterator<>本身。但是,与reverse_iterator:相比,base()确实针对先前的元素

http://en.cppreference.com/w/cpp/iterator/reverse_iterator

让我有点困扰的是,当我有std::distancebegin()(或rend().base())时:

  std::cout << "n" 
        << "Reverse Iterator now points to " 
        << *revIter << "-" << *(revIter.base())<< "-" 
        << std::distance(revIter.base(), myList.rend().base()); 

我有:

反向迭代器现在指向2-4-3

反向迭代程序现在指向3-4-3

或者我期望第二个是";3-4-4";由于元素是在CCD_ 9之前插入的。。。