如何处理std :: find_if()返回false?

A__*_*A__ 4 c++ algorithm iterator stdvector c++11

采取以下示例,示例取自cplusplus.com参考页,并更改为return false

// find_if example
#include <iostream>     // std::cout
#include <algorithm>    // std::find_if
#include <vector>       // std::vector

bool IsOdd (int i) {
  return ((i%2)==1);
}

int main ()
{
  std::vector<int> myvector;    
  myvector.push_back(10);
  myvector.push_back(20);
  myvector.push_back(40);
  myvector.push_back(50);

  std::vector<int>::iterator it = std::find_if (myvector.begin(), myvector.end(), IsOdd);
  std::cout << "The first odd value is " << *it << '\n';

  return 0;
} 
Run Code Online (Sandbox Code Playgroud)

由于in myvector中的值都不是奇数,因此它将返回InputIterator last,它是未定义的:

The first odd value is -1727673935
Run Code Online (Sandbox Code Playgroud)

处理此输出的正确方法是什么?

我如何知道std::find_if()返回false的结果是否是不可预测的,并且与整个向量进行比较以确认结果值不存在,从而挫败了std::find_if()开始使用的目的?

Vla*_*cow 8

你的意思是

std::vector<int>::iterator it = std::find_if (myvector.begin(), myvector.end(), IsOdd);

if ( it != myvector.end() )
{
    std::cout << "The first odd value is " << *it << '\n';
}
else
{
    // std::cout << "there is no odd value in the vector\n";
}
Run Code Online (Sandbox Code Playgroud)


JeJ*_*eJo 5

std::find_if返回(参考cppreference.com

迭代器到满足条件的第一个元素或最后一个元素(如果没有 找到这样的元素)

这意味着,仅当迭代器不等于 container.end()迭代器时,才取消引用迭代器。

if (const auto iter = std::find_if(myvector.cbegin(), myvector.cend(), IsOdd); // need C++17 compiler support
    iter != myvector.cend())
{
    std::cout << *iter << "\n";
}
else
{
    // code
}
Run Code Online (Sandbox Code Playgroud)

PS:在现代 C++ 中,lambda 表达式应该是你的好朋友,并在适当的时候使用它。在这里查看更多内容:为什么编译器可以比普通函数更好地优化 lambda?

这意味着你IsOdd本来可以

constexpr auto isOdd = [](const int i) /* noexcept */ { return i & 1; };
Run Code Online (Sandbox Code Playgroud)


Bre*_*ent 5

惯用的方法是检查迭代器是否等于末尾。

auto it = std::find_if (myvector.begin(), myvector.end(), IsOdd);
if (it == myvector.end()) {
    std::cout << "No odd values found" << std::endl;
} else {
    std::cout << "The first odd value is " << *it << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

在C ++ 17(最新标准)中,您可以在以下if语句中声明迭代器:

if (auto it = std::find_if(myvector.begin(), myvector.end(), IsOdd); it != myvector.end()) {
    std::cout << "The first odd value is " << *it << std::endl;
} else {
    std::cout << "No odd values found" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)


lub*_*bgr 5

您需要检查返回的迭代器是否是您传递给的最终迭代器std::find_if(第二个参数)。这些语义对于标准库中的算法非常普遍,因此您应该习惯这一点。

const auto firstOdd = std::find_if (myvector.cbegin(), myvector.cend(), IsOdd);

if (firstOdd != myvector.cend())
    std::cout << "The first odd value is " << *it << '\n';
else
    std::cout << "No odd values found\n";
Run Code Online (Sandbox Code Playgroud)

还请注意,您可以使用cbegin()/ cend()成员函数,因为您无需更改容器。

  • “ *比较等于**您正在搜索的容器的**最后一遍迭代器**” –更准确地说,它应该是“传递给find_if()的最终迭代器”,而是在特定情况下*成为容器的最后一站迭代器,但通常在使用迭代器时并非总是如此。 (2认同)