我刚刚注意到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)。我没有用任何其他版本或编译器测试它。)
答案 0 :(得分:10)
将迭代器递减到begin
以外会调用未定义的行为。你看到的行为很可能是巧合(事实上,看看不同的编译器here会发生什么)。
如果你想确认一下,你可以简单地看一下GCC list
的实施情况;您通常可以在/usr/include/c++/4.x.y/bits/stl_list.h
找到来源。
答案 1 :(得分:1)
看着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 :(得分:0)
我认为你得到的“2”是常数2(在alist.push_back(2);
中)。
我认为你的节目非常简短,我是对的吗?