将STL容器与迭代器一起使用有什么常见的误用?

yes*_*aaj 12 c++ iterator stl

STL容器与迭代器一起使用有什么常见的误用?

Rob*_*lls 21

如果通过插入或擦除容器成员来更改容器,则忘记迭代器经常失效.

关于使用STL的许多重要提示我强烈推荐Scott Meyers的书"Effective STL"(已清理亚马逊链接)

  • 我普遍同意,但有可能将您的陈述解释为"迭代器*总是*通过插入或删除而无效".通过删除*later*元素永远不会使向量迭代器失效,并且插入或删除其他元素都不会使列表,集合和映射迭代器无效. (2认同)

Mat*_*son 9

结束范围检查应该使用!=而不是<因为指针的顺序不能保证.

例:

for(it = list.begin(); it != list.end(); ++it)
{
     // do stuff
}
Run Code Online (Sandbox Code Playgroud)


Dav*_*ner 8

预递增时的后递增将执行.

  • 编译器不一定能生成相同的代码,具体取决于迭代器的实际内容.i ++生成一个临时值,不能总是优化掉.++我只是做增量. (4认同)

小智 7

其他几个:

  • 将反向迭代器转换为基本迭代器,而不记住迭代器现在将是它指向的迭代器之外的一个元素.

  • 尝试使用需要随机访问迭代器的算法以及集合和映射之类的迭代器.

  • 使用非const迭代器编辑映射条目的键(这恰好构建在VS.Net上,但不会与GCC一起构建)


Mar*_*aas 6

使用它们而不阅读Scott Meyers的"Effective STL"一书.:)真的.这使得大多数愚蠢的错误都消失了.


Reu*_*nen 6

适当延续之后erase().

假设:

Container::iterator i = cont.begin(), iEnd = cont.end();
Run Code Online (Sandbox Code Playgroud)

例如std::map,这不是一个好主意:

for (; i != iEnd; ++i) {
    if (i->second.eraseCondition()) {
        cont.erase(i);
    }
}
Run Code Online (Sandbox Code Playgroud)

这可行:

for (; i != iEnd; ) {
    Container::iterator temp = i;
    ++temp;
    if (i->second.eraseCondition()) {
        cont.erase(i);
    }
    i = temp;
}
Run Code Online (Sandbox Code Playgroud)

这也是:

for (; i != iEnd; ) {
    if (i->second.eraseCondition()) {
        cont.erase(i++);
    }
    else {
        ++i;
    }
}
Run Code Online (Sandbox Code Playgroud)

真的太多次,我不得不在一些生产代码中应用这些修复:(