std::list是一个循环列表!!等等,什么

std::list is a cyclic list!! wait, what?

本文关键字:列表 循环 什么 一个 等等 list std      更新时间:2023-10-16

我正在编写一个测试程序,发现了一个非常有趣的std::list行为案例。

#include <list>
#include <algorithm>
#include <iostream>
int main()
{
    std::list<int> mylist;
    std::list<int>::iterator iter;
    for(int i=3; i<10; ++i){
        mylist.push_back(i);
    }
    iter = mylist.begin();
    iter--;
    iter--;
    std::cout<<*iter<< std::endl;
    std::cout<<std::distance(mylist.end(), mylist.begin())<<std::endl;
}

输出为:

9  
1  

如果我没有记错的话,这种行为与循环列表有关。我从来没有遇到过一个论坛、书籍或讨论,其中提到标准列表是一个循环列表。我的GCC版本是4.1.2。那么我是对的吗?标准std::list是一个循环列表吗?

否,std::list不是循环的。当您递减迭代器时,您的代码具有未定义的行为。当您调用std::distance(mylist.end(), mylist.begin())时,它也有未定义的行为,因为通过递增mylist.end()无法访问mylist.begin()

请注意,当您调用未定义的行为时,std::list很可能看起来是循环的,因为当行为未定义时,"std::list appeared to be cyclic"符合允许的行为范围。这个范围是,任何行为。

即使它在这个实现中是循环的,您也不必依赖它,因为这个属性不受标准的保证。此外,开始指针的递减是未定义的行为以及std::distance调用。

事实上,可以通过以下方式实现该列表,从而获得可观察到的结果:

list
  head --> listelem1 (or elEnd)
  begin() return head;
  end()   return head->prev;
listelem1           listelem2           listelem3           elEnd              
     ptr  = d1           ptr  = d2           ptr  = d3           ptr  = nullptr
     next = le2          next = le3          next = elEnd        next = le1
     prev = elEnd        prev = le1          prev = le2          prev = le3

但这取决于库的实现者,只要他遵循标准的接口和行为要求。