【问题标题】:Can I check a C++ iterator against null?我可以针对 null 检查 C++ 迭代器吗?
【发布时间】:2017-05-12 04:46:47
【问题描述】:

我在使用矢量迭代器时遇到了问题。我在几个地方读到过,检查空迭代器是不可能的,检查迭代器的常用方法是在搜索后根据 vector.end() 检查它。比如:

vector< Animal* > animalList;

vector<Animal*>::iterator findInList(const type_info& type)
{
    // Loop through list of Animals, if Dog found, return iterator to it
}

auto it = findInList(typeid(Dog));
// With a pointer I can check if it's null, but with an iterator I have to check against animalList.end();

问题是容器可能是空的。使用迭代器,我无法返回 null 以指示容器为空或搜索失败。我可以返回 vector::end(),但是 cplusplus.com 说:

If the container is empty, vector::end() function returns the same as vector::begin()

然后对于 vector::begin() 它说:

If the container is empty, the returned iterator value shall not be dereferenced.

所以如果我有一个空容器,vector::end() 和 vector::begin() 指向同一个地方,我认为我不能取消引用它,我什至不确定它指向分配的内存。

编辑:谢谢大家。当您迭代出来时,vector::end() 或 vector::begin() 不会取消引用迭代器,我可以安全地检查 vector::end()。

【问题讨论】:

  • 返回一个空向量的迭代器。当调用者在迭代器上循环时,循环将立即结束,并且他们永远不会取消对迭代器的引用。
  • 您是否试图避免暴露您在内部使用的容器,因此犹豫是否提供一种方法让用户根据您的容器本身的end 检查返回值?跨度>
  • 迭代器不是指针。
  • “所以如果我有一个空容器......我认为我不能取消引用它” 如果您返回可能为空的指针,情况也是如此.
  • @jaggedSpire,现在必须。好吧,我希望该功能尽可能多地处理。我想从我理解的答案中,我可以得到与 vector::end() 相同的行为检查,也就是说,与返回指针并检查 nullptr 相同。

标签: c++ pointers vector iterator nullptr


【解决方案1】:

您不需要检查迭代器是否为空,因为它永远不会。您需要检查返回的迭代器是否与容器的end() 位置不同。如果是,您可以通过*it 安全地取消对迭代器的引用。

如果容器为空,则返回的迭代器值不应被取消引用。 因此,如果我有一个空容器,vector::end() 和 vector::begin() 指向同一个地方,我认为我不能取消引用它,我什至不确定它是否指向分配的内存。

不,检查 if(myIt != container.end()) 不会取消对迭代器的引用。迭代器解引用是通过*myIt 完成的,这意味着获取迭代器指向的对象的值。从同一个容器检查迭代器到其他迭代器总是安全的,取消引用不指向容器元素的迭代器是不安全的。

【讨论】:

  • 啊,我明白我误解了什么。针对 .end() 检查迭代器并没有取消引用它,谢谢。
  • @TitoneMaurice 如果我帮助请将问题标记为已回答,它会在谷歌索引中对其他人可见,并且不会显示在未回答的问题列表中。谢谢。
  • “将迭代器检查到其他迭代器总是安全的” 嗯,不,迭代器必须是有效的(这包括过去的结束),并且它们必须引用同一个容器。
  • @LightnessRacesinOrbit 更新了 anwser,包含有关同一容器的信息。没有 stl 算法将返回“过去的最后一个”迭代器。它将返回 end()。用户必须手动增加这样的迭代器,如果开发者想伤害自己,他总会找到办法:)谢谢你指出。
  • @paweldac: end() 过去的迭代器。
【解决方案2】:

像这样检查

auto it = findInList( someInfo );

if ( it == animalList.end() ) std::cout << "not found";

【讨论】:

  • 这种风格不好。您已经抽象出一个名为 findInList 的函数背后的容器,但现在您必须立即打破该抽象并直接与容器进行比较。要么首先使用.find,要么找到另一种方式来表示未找到的情况。
【解决方案3】:

不,您不能检查 NULL,因为它不是指针。返回并检查animalList.end()。只有当迭代器不等于end() 时才应该取消引用它。

【讨论】:

    猜你喜欢
    • 2018-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-06
    • 2020-04-23
    • 2019-09-08
    • 2011-12-22
    • 1970-01-01
    相关资源
    最近更新 更多