0

我正在遍历两个 STL 列表(L1、L2),如下所示:

list<int>::const_iterator itr1 = L1.begin();
list<int>::const_iterator itr2 = L2.begin();

for (itr1; itr1 != L1.end(); itr1++) {
   if (*itr1 < *itr2) {
     //some code
   }

}

它编译得很好,但是当我运行它时,它说“表达式:列表迭代器不可取消引用”

现在在课堂上,我们制作了 STL 列表的模拟版本,我们在其中编写了自己的 STL 列表,并且我们重载了 *operator 以取消引用迭代器。但是,显然它在这里不起作用。

如何取消引用迭代器,或者如果 STL 列表以不同的方式执行,它是如何执行的。我浏览了这个:

http://www.sgi.com/tech/stl/List.html

文档并且似乎没有找到任何接受成员“引用”但仍然没有看到如何引用迭代器指向的内容,除非它是列表的第一部分或最后一部分。

有人知道这里发生了什么吗?谢谢

这是一个粘贴箱:

http://pastebin.com/YRddqjmN

4

5 回答 5

3

我猜:

L2为空,因此L2.begin()与 相同L2.end()

这意味着L2.begin()返回一个不可引用的迭代器,因此您正在调用未定义的行为。

于 2011-04-27T01:24:07.647 回答
3

此(特定于实现)消息向我表明您取消引用了一个无效的迭代器。这与语法/编译时语义无关,因此您的编译器没有抱怨也就不足为奇了。但是请注意,迭代器确实具有运行时语义:在这种情况下,我敢打赌代码是用一个空L2列表调用的,所以itr2 == L2.end(). 这意味着这*itr2会导致未定义的行为。幸运的是,这似乎触发了错误消息,而不是在你的脸上炸毁。

于 2011-04-27T01:29:35.280 回答
2
while ( *itr2 < *itr1 ) {
    itr2++;
}

该代码没有检查是否在 L2 结束时运行。也许添加一个检查itr2 != L2.end()

于 2011-04-27T01:33:58.217 回答
0

只要列表不为空,标准列表迭代器就可以被取消引用,只要它在列表范围内,即 [ list.begin(), list.end() )。

于 2011-04-27T01:29:49.123 回答
0

其他答案是正确的,因为两个错误,一个坏的列表迭代器被取消引用。看着你的粘贴箱,

这种情况是倒退的:

if ( (*itr1 == *itr2) && (itr2 != L2.end()) ) {

它应该是

if ( (itr2 != L2.end()) && (*itr1 == *itr2) ) {

为了在使用它之前检查itr2是否有效。另外,第一个条件

if ( L1.empty() && L2.empty() ) {
            cout << "Returning an empty list because the two arugment lists were empty\n\n";

应该是析取:

if ( L1.empty() || L2.empty() ) {
            cout << "Returning an empty list because at least one of the two argument lists was empty\n\n";

但这甚至不是必需的。

(哦,你知道set_intersection 吗,它是标准库的一部分?)

于 2011-04-27T01:35:00.963 回答