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

Edu*_*yan 1 c++ algorithm containers list 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;
}
Run Code Online (Sandbox Code Playgroud)

输出是:

9  
1  
Run Code Online (Sandbox Code Playgroud)

如果我没有弄错,这种行为与循环列表有关.我从未见过论坛,书籍或讨论,其中提到标准列表是循环列表.我的GCC版本是4.1.2.我是对的吗?标准std::list是循环列表吗?

Ben*_*ley 15

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

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

  • 问题难度与upvote计数之间的反比例性定律.问题越难,理解答案足以投票的人口越少.类似的法律涉及到问题的默默无闻. (5认同)
  • @EduardRostomyan:如果需要,您可以查看标准库实现,以确切了解发生的情况.但是`std :: distance`的规范要求通过递增前0次或更多次来达到第二个参数.它还说,对于标准容器,将迭代器递减到`begin()`迭代器之前,或者将迭代器递增到`end()`迭代器之后,是未定义的行为. (4认同)
  • @EduardRostomyan,行为未定义 - 它可以做任何事情 - 从将迭代器设置为距离末尾距离 1 处的无效值,到折叠可观察的宇宙(到目前为止,我认为没有任何编译器实现可以折叠)可观测的宇宙——但理论上他们可以)。 (3认同)
  • @EduardRostomyan:你对`std :: distance`的调用也是未定义的行为. (2认同)