【问题标题】:How to check whether STL iterator points at anything? [duplicate]如何检查 STL 迭代器是否指向任何东西? [复制]
【发布时间】:2010-10-23 21:00:09
【问题描述】:

可能重复:
C++ Best way to check if an iterator is valid

我想做这样的事情:

std::vector<int>::iterator it;
// /cut/ search for something in vector and point iterator at it. 
if(!it) //check whether found
    do_something(); 

但是没有运算符!对于迭代器。如何检查迭代器是否指向任何东西?

【问题讨论】:

  • 在不引用它正在迭代的容器的情况下使用迭代器是没有意义的。请参阅詹姆斯霍普金的回答。
  • 澄清STL迭代器的黑暗失效:angelikalanger.com/Conferences/Slides/…
  • 投票重新打开,因为:1)目标问题较新,因此应该是另一个与此问题重复的问题。 2)问题不是接缝:这询问迭代器是否不是结束迭代器,而另一个询问无效的迭代器。

标签: c++ stl iterator


【解决方案1】:

你不能。通常的习惯用法是使用容器的结束迭代器作为“未找到”标记。这就是std::find 返回的内容。

std::vector<int>::iterator i = std::find(v.begin(), v.end(), 13);
if (i != v.end())
{
     // ...
}

对未赋值的迭代器唯一能做的就是给它赋值。

【讨论】:

  • 您介绍了迭代器已初始化且仍然有效的情况。但是,某些容器上的某些操作可能会使迭代器无效。例如,从向量中删除元素可能会使迭代器无效(在这种情况下,迭代器指向向量中的最后一个元素)。
  • @Cătălin:这都是真的,但我认为超出了问题的范围。就像! (not) 运算符仅适用于有效或空指针,上述仅适用于有效迭代器(包括end 迭代器)。
  • 迭代器有效性是程序员需要担心的事情。你是唯一需要确保你的迭代器没有做坏事的人。
【解决方案2】:

如果你想在循环中使用迭代器,最安全的使用方式是:

for (std::vector<int>::iterator it = v.begin(); it != v.end(); ++it)
{
 do_smth();
}

【讨论】:

  • 实际上很多标准算法都返回迭代器(例如find)和容器上的方法(例如map::find)
  • 这是安全的,除非循环执行 'erase(it)',因为在擦除之后,'it' 变为无效,随后的 '++it' 无效。
  • 不回答问题
【解决方案3】:

虽然迭代器被认为是指针的一般形式,但它们并不完全是指针。该标准定义了Past-the-end 迭代器来指示容器中的搜索失败。因此,不建议检查迭代器是否为 NULL

Past-the-end 值是非奇异且不可解引用的。

if(it != aVector.end())  //past-the-end iterator
    do_something();

【讨论】:

    【解决方案4】:

    我相信这通常会给你一个很好的测试:

    if (iterator._Mycont == &MyContainer)
    {
    Probably a valid iterator!
    }
    

    您可以进行测试以确保迭代器不等于结尾...

    iterator != MyContainer.end()
    

    和:

    iterator >= MyContainer.begin()
    

    【讨论】:

    • 似乎非常依赖编译器(和版本!)。
    猜你喜欢
    • 2021-09-03
    • 2020-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多