Take the following example taken from the cplusplus.com reference page and altered to 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;
}
Since no value in myvector
is odd it will return InputIterator last, which is undefined:
The first odd value is -1727673935
What is the proper way to handle this output?
How can I know std::find_if()
returned false
if the output is unpredictable and comparing to the entire vector to confirm the resulting value doesn't exist defeats the purpose of using std::find_if()
to begin with?
Do you mean
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";
}
The idiomatic way to do this is to check whether the iterator equals the end sentinel.
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;
}
In C++17 (the most recent standard), you can declare the iterator right in the if
statement:
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;
}
You need to check if the returned iterator is the end iterator you passed to std::find_if
(the second argument). These semantics are quite common for algorithms in the standard library, so you should get used to this.
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";
Note also that you can use the cbegin()
/cend()
member functions, as you're not mutating the container.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With