C++ <algorithm> std::find_if_not
The std::find_if_not
function in C++ is part of the <algorithm> header and is used to search for the first element in a range that does not satisfy a specified condition, defined by a unary predicate. If such an element is found, it returns an iterator to it; otherwise, it returns the end iterator.
Syntax of std::find_if_not
template <class InputIterator, class UnaryPredicate>
InputIterator find_if_not(InputIterator first, InputIterator last, UnaryPredicate pred);
Parameters of std::find_if_not
Parameter | Description |
---|---|
first | An input iterator to the initial position in a sequence. |
last | An input iterator to the final position in a sequence (one past the last element). |
pred | A unary predicate that accepts an element in the range as an argument and returns a value convertible to bool . The value returned indicates whether the element satisfies the condition. The function shall not modify its argument. This can either be a function pointer or a function object. |
Return Value of std::find_if_not
An iterator to the first element in the range for which pred
returns false
. If pred
returns true
for all elements, the function returns last
.
Exceptions for std::find_if_not
Throws if either pred
or an operation on an iterator throws. Note that invalid parameters cause undefined behavior.
Examples for std::find_if_not
Example 1: Using std::find_if_not to Find the First Even Number
In this example, we use std::find_if_not
to search for the first even number in a vector.
Program
#include <iostream>
#include <vector>
#include <algorithm> // For std::find_if_not
bool is_odd(int n) {
return n % 2 != 0;
}
int main() {
std::vector<int> numbers = {1, 3, 5, 6, 7};
auto it = std::find_if_not(numbers.begin(), numbers.end(), is_odd);
if (it != numbers.end())
std::cout << "The first even number is " << *it << '\n';
else
std::cout << "No even numbers found\n";
return 0;
}
Output
The first even number is 6
Explanation
- We include the necessary headers:
<iostream>
for input/output operations,<vector>
for thestd::vector
container, and<algorithm>
for thestd::find_if_not
function. - We define a function
is_odd
that takes an integer and returnstrue
if the integer is odd, andfalse
otherwise. - We create a vector
numbers
containing the integers 1, 3, 5, 6, and 7. - We use
std::find_if_not
to search for the first even number in the vector by passing theis_odd
function as the predicate. - If an even number is found,
it
points to the element, and we print its value. Otherwise, we print that no even numbers were found.
Example 2: Using std::find_if_not with a Lambda Function
This example demonstrates how to use std::find_if_not
with a lambda function to find the first number not greater than 10 in a vector.
Program
#include <iostream>
#include <vector>
#include <algorithm> // For std::find_if_not
int main() {
std::vector<int> numbers = {12, 15, 8, 20, 25};
auto it = std::find_if_not(numbers.begin(), numbers.end(), [](int n) {
return n > 10;
});
if (it != numbers.end())
std::cout << "The first number not greater than 10 is " << *it << '\n';
else
std::cout << "All numbers are greater than 10\n";
return 0;
}
Output
The first number not greater than 10 is 8
Explanation
- We include the necessary headers:
<iostream>
for input/output operations,<vector>
for thestd::vector
container, and<algorithm>
for thestd::find_if_not
function. - We create a vector
numbers
containing the integers 12, 15, 8, 20, and 25. - We use
std::find_if_not
with a lambda function that takes an integer and returnstrue
if the integer is greater than 10. - If a number not greater than 10 is found,
it
points to the element, and we print its value. Otherwise, we print that all numbers are greater than 10.
Example 3: Using std::find_if_not with a Custom Predicate
In this example, we use std::find_if_not
to find the first string in a vector that does not start with the letter ‘A’.
Program
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
bool start_with_A(const std::string& s) {
return s.empty() || s[0] == 'A';
}
int main() {
std::vector<std::string> names = {"Alice", "Bob", "Anna", "Charlie"};
auto it = std::find_if_not(names.begin(), names.end(), start_with_A);
if (it != names.end()) {
std::cout << "The first name not starting with 'A' is " << *it << '\n';
} else {
std::cout << "All names start with 'A'.\n";
}
return 0;
}
Output
The first name not starting with 'A' is Bob
Explanation
- We include the necessary headers:
<iostream>
for input/output operations,<vector>
for thestd::vector
container,<string>
for handling strings, and<algorithm>
for thestd::find_if_not
function. - We define a predicate function
start_with_A
that checks if a string starts with the letter ‘A’. - We create a vector
names
containing the strings “Alice”, “Bob”, “Anna”, and “Charlie”. - We use
std::find_if_not
to find the first name in the vector that does not start with the letter ‘A’. - If a match is found,
it
points to the element, and we print its value. Otherwise, we print that all names start with ‘A’.
Examples for Exceptions Thrown by std::find_if_not
The std::find_if_not
function can throw exceptions in the following cases:
- If the predicate function (
pred
) throws an exception. - If an operation on the iterators, such as dereferencing or incrementing, throws an exception.
Example 1: Predicate Throws an Exception
This example demonstrates a case where the predicate function throws an exception during execution.
Program
#include <iostream>
#include <vector>
#include <algorithm>
#include <stdexcept>
bool faulty_predicate(int n) {
if (n < 0) {
throw std::runtime_error("Negative number encountered.");
}
return n % 2 != 0;
}
int main() {
std::vector<int> numbers = {1, 3, -5, 7, 9};
try {
auto it = std::find_if_not(numbers.begin(), numbers.end(), faulty_predicate);
if (it != numbers.end()) {
std::cout << "Element found: " << *it << std::endl;
} else {
std::cout << "No element satisfies the condition." << std::endl;
}
} catch (const std::runtime_error& e) {
std::cout << "Exception caught: " << e.what() << std::endl;
}
return 0;
}
Output
Exception caught: Negative number encountered.
Explanation
- The program defines a predicate function
faulty_predicate
that throws astd::runtime_error
if a negative number is encountered. - A vector
numbers
is initialized, including a negative number (-5). - The
std::find_if_not
function applies the predicate to each element of the vector. When it encounters the negative number, the predicate throws an exception. - The exception is caught in the try-catch block, and an error message is displayed.
Example 2: Iterator Throws an Exception
This example demonstrates a case where a custom iterator throws an exception during iteration.
Program
#include <iostream>
#include <vector>
#include <algorithm>
#include <stdexcept>
class FaultyIterator {
public:
using iterator_category = std::input_iterator_tag;
using value_type = int;
using difference_type = std::ptrdiff_t;
using pointer = const int*;
using reference = const int&;
FaultyIterator(const int* ptr, bool fail_after = false)
: ptr(ptr), fail_after(fail_after), count(0) {}
reference operator*() const {
if (fail_after && count >= 2) {
throw std::runtime_error("Iterator error during dereference.");
}
return *ptr;
}
FaultyIterator& operator++() {
++ptr;
++count;
return *this;
}
bool operator!=(const FaultyIterator& other) const {
return ptr != other.ptr;
}
private:
const int* ptr;
bool fail_after;
int count;
};
bool is_positive(int n) {
return n > 0;
}
int main() {
int arr[] = {1, 2, 3};
try {
auto it = std::find_if_not(
FaultyIterator(arr, true),
FaultyIterator(arr + 3),
is_positive
);
if (it != FaultyIterator(arr + 3)) {
std::cout << "Element found: " << *it << std::endl;
} else {
std::cout << "No element satisfies the condition." << std::endl;
}
} catch (const std::runtime_error& e) {
std::cout << "Exception caught: " << e.what() << std::endl;
}
return 0;
}
Output
Exception caught: Iterator error during dereference.
Explanation
- The program defines a custom iterator
FaultyIterator
that throws astd::runtime_error
exception after accessing two elements. - An array
arr
is initialized with three elements. - The
std::find_if_not
function searches for the first element that does not satisfy the predicateis_positive
. - The iterator throws an exception during the third access, which is caught in the
try-catch
block. - An error message is printed to indicate the exception.