标准模板库列表 - 双重链接或循环链接
Standard Template Library lists - doubly linked or circularly linked?
我刚刚注意到C++中std::list
类的一些事情,我觉得很好奇。简而言之,它涉及列表迭代器的工作方式。请考虑以下代码:
std::list<int> alist;
alist.push_back(0);
alist.push_back(1);
alist.push_back(2);
显然,这将创建一个包含三个整数元素的列表。我可以在列表的开头定义一个迭代器,并使用它来打印出第一个元素中包含的值,如下所示:
std::list<int>::iterator iter = alist.begin();
std::cout << *iter << std::endl; // Prints "0" to stdout
我觉得有点奇怪的是,如果我现在递减迭代器,它会"循环"并最终指向列表中的最后一个元素:
--iter;
std::cout << *iter << std::endl; // Prints "2" to stdout
对于应该作为双向链表实现的东西来说,这是合理的行为吗?如果列表是一个循环链表,我非常希望迭代器有类似的行为,但我觉得这很奇怪。
您过去使用过的这种迭代器行为是否有任何实际用途?是否有任何与这种行为相关的陷阱,我应该注意?
(顺便说一下,这发生在 gcc 4.7.0 (MinGW( 中。我还没有用任何其他版本或编译器测试过它。
将
迭代器递减到超出begin
会调用未定义的行为。 你看到的行为很可能是巧合(事实上,看看这里不同的编译器会发生什么(。
如果你想确认这一点,你可以简单地看看GCC list
的实现;你通常可以在/usr/include/c++/4.x.y/bits/stl_list.h
找到源代码。
查看stl_list.h,我注意到以下评论:
*
* Second, a %list conceptually represented as
* @code
* A <---> B <---> C <---> D
* @endcode
* is actually circular; a link exists between A and D. The %list
* class holds (as its only data member) a private list::iterator
* pointing to @e D, not to @e A! To get to the head of the %list,
* we start at the tail and move forward by one. When this member
这是在 4.2.1 gcc 中找到的。这不会改变@Oli提供的答案,因为它恰好是在 gcc 4.2.1 中实现的答案。我会依靠该功能
我认为你得到的"2"是常数 2(在 alist.push_back(2);
中(。我认为你的程序非常简短和简单,对吗?
相关文章:
- 下面是我为检测链接列表中的循环而制作的代码
- 如何使用由for循环创建的向量向量构建链接列表
- 我如何使我的循环转到char*阵列的尽头,并将每个城市都放在链接的列表中(城市被划分为白色的空间)
- 永远循环的链接列表破坏者
- C++循环链接列表 - 删除所有节点
- 从自定义链接列表中打印值时,循环陷入无限时
- 做循环静态链接的LIB会导致更大的输出尺寸
- 我写了一个函数来删除循环链接列表中的第 1 个节点,但输出显示无限次"55 44 33 22 11 99",那么我该如何解决呢?
- 我的链接列表打印功能进入无限循环
- 该功能检测循环链接列表的时间复杂性是什么?
- 为什么一个循环需要电流>链接 !=NULL 和一个电流 != NULL 作为我的链表?
- 使用循环在链接列表的前面插入一个节点
- 标准库中的双链接循环列表
- 努力将双重链接的通用列表转移到循环中.(segfault)
- 删除循环链接列表中的项目
- 循环包含导致链接错误的语句
- 正在从循环双链接列表中删除节点
- 标准模板库列表 - 双重链接或循环链接
- 通过两次链接同一个库来解决循环依赖关系
- 使用while循环创建链接列表