以以下示例为例,该示例取自the cplusplus.com reference page,并更改为返回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;
}
由于myvector
中的任何值都不为奇数,它将返回 InputIterator last ,该值未定义:
The first odd value is -1727673935
处理此输出的正确方法是什么?
我怎么知道std::find_if()
返回了false
,如果输出是不可预测的,并且与整个向量进行比较以确认结果值不存在,这使使用std::find_if()
开始与?
答案 0 :(得分:7)
你是说
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";
}
答案 1 :(得分:4)
惯用的方法是检查迭代器是否等于末尾。
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;
}
在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;
}
答案 2 :(得分:4)
您需要检查返回的迭代器是否是传递给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";
还请注意,您可以使用cbegin()
/ cend()
成员函数,因为您无需更改容器。
答案 3 :(得分:3)
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
}
PS :在现代C ++中,lambdas表达式应该是您的好朋友,并在适当时使用它。 在此处查看更多信息:Why can lambdas be better optimized by the compiler than plain functions?
这意味着您的IsOdd
本来可以
constexpr auto isOdd = [](const int i) /* noexcept */ { return i & 1; };