【问题标题】:What does std::find return if element not found如果找不到元素,std::find 会返回什么
【发布时间】:2016-07-24 11:49:17
【问题描述】:

根据文档,std::find 返回

最后

如果没有找到元素。那是什么意思?它是否返回一个指向容器中最后一个元素的迭代器?还是返回一个指向.end() 的迭代器,即指向容器外部? 以下代码打印0,它不是容器的元素。所以,我猜std::find 在容器外返回一个迭代器。你能确认一下吗?

int main()
{
    vector<int> vec = {1, 2,3, 1000, 4, 5};
    auto itr = std::find(vec.begin(), vec.end(), 456);
    cout << *itr;
}

【问题讨论】:

    标签: c++ algorithm c++11 iterator


    【解决方案1】:

    算法适用于由一对迭代器定义的范围。这些迭代器作为参数传递给算法。第一个迭代器指向范围内的第一个元素,第二个参数指向范围末尾的一个元素。可能失败的算法在失败时会返回一个过去的迭代器的副本。这就是 std::find 所做的:如果没有匹配的元素,它会返回它的第二个参数。

    请注意,前一段没有使用“容器”一词。容器具有成员函数,可为您提供可用于获取容器元素的范围,但也有创建与任何容器无关的迭代器的方法。

    【讨论】:

    • 你不使用容器,那么你使用哪一个?算法还是范围?@Pete Becker
    • @YuanWen -- 算法的规范不使用容器。该算法可以通过使用指向容器的迭代器调用它来应用于容器的内容。您可以通过在容器上调用 begin()end() 来获取这些迭代器。
    【解决方案2】:

    根据this 文档,它的字面意思是:

    "返回值: 迭代到满足条件的第一个元素,如果没有找到这样的元素,则迭代到最后一个元素。”

    在你的情况下,它是向量的一倍,.end()

    【讨论】:

      【解决方案3】:

      lastfind 的第二个参数的名称。它不知道你使用的是哪种容器,只知道你给它的迭代器。

      在您的示例中,lastvec.end(),(根据定义)它是不可取消引用的,因为它是最后一个元素之后的一个。因此,通过取消引用它,您会调用未定义的行为,在这种情况下表现为打印出 0。

      【讨论】:

      • 不过,你应该可以做到if find(vec.begin(), vec.end(), ...) != vec.end()...
      • 无论 vec 是什么类型,*(vec.end()) 总是返回 0 吗?@First Jens @Cameron
      • @Yuan: 不。因为取消引用vec.end()未定义的行为,它每次都可能返回不同的值。或者崩溃。或者在其他地方破坏其他一些记忆,但似乎返回了一些合理的东西。或者,或者,或者... ;-) 在这种特殊情况下,取消引用它可能会导致在向量的元素被解释为元素之后发生在内存中的任何内容,当时该元素为 0,但很容易被任何垃圾值。
      • 那么对于每一个迭代器,如果我们想做*iterator,我们最好确保它是有效的?First Jens贴的代码有bug?@Cameron
      • @Yuan:是的,没错。首先,Jens 在取消引用迭代器之前缺少对 findvec.end() 的结果的比较。
      猜你喜欢
      • 1970-01-01
      • 2014-02-02
      • 1970-01-01
      • 2018-02-12
      • 1970-01-01
      • 2023-04-05
      • 2011-02-04
      • 2021-05-12
      • 1970-01-01
      相关资源
      最近更新 更多