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

时间:2014-09-19 11:01:22

标签: c++ algorithm list containers stdlist

我正在编写一个测试程序,发现了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是循环列表吗?

2 个答案:

答案 0 :(得分:15)

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

请注意,当您调用未定义的行为时,std::list可能看起来是循环的,因为&#34; std :: list看起来是循环的&#34;当行为未定义时,适合允许的行为范围。这个范围是任何行为。

答案 1 :(得分:2)

即使它在此实现中是循环 ,您也不必依赖它,因为标准不保证此属性。 您的开始指针的递减也是未定义的行为以及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

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