12

检查此代码:

#include "stdafx.h"
#include <list>

int _tmain(int argc, _TCHAR* argv[])
{
    std::list<int> mylist;
    mylist.push_back(1);
    std::list<int>::iterator i = mylist.end();
    if( i == mylist.end() )
        printf( "end is end\n" );

    mylist.clear();
    if( i == mylist.end() )
        printf( "never get here because Microsoft seems to "
                "think the iterator is no longer safe.\n" );

    return 0;
}

现在,根据cplusplus.com的说法,这应该不是问题,在发布模式下,我认为这很好,不会引起任何问题,但调试变得不可能,因为这只是让我继续下去。任何指针?

4

3 回答 3

13

其他答案指出,一般来说,您不能依赖容器的结束后迭代器在容器被清除时保持有效。但是,列表的结束迭代器确实应该保持有效:

C++11 23.3.5.4/3效果:仅使迭代器和对已擦除元素的引用无效。

过去的迭代器不引用任何元素,因此不应无效。

于 2013-02-01T13:37:39.433 回答
4

从 C++11 开始,表 100(序列容器要求):

clear()[...] 可能会使过去的迭代器无效。

当然std::list是一个序列容器模板(23.3.5.1/2):

列表满足容器、可逆容器(在 23.2 中的两个表中给出)、序列容器(包括大多数可选序列容器要求(23.2.3)和分配器感知容器)的所有要求(表 99)。例外是未提供的 operator[] 和 at 成员函数。此处仅针对这些表之一中未描述的列表上的操作或存在附加语义信息的操作提供描述。

于 2013-02-01T13:20:30.467 回答
-2

这实际上是无效的。迭代器仅在当前状态容器上有效。添加或删除项目后,迭代器将不再有效。

您链接的文章并未说明您在做什么是有效的。他们在清除后得到一个新的迭代器。

它没有出现在发布代码中的原因是因为发现问题的调试被禁用。

于 2013-02-01T13:13:30.673 回答