C++ <algorithm> std::find_if

The std::find_if function in C++ is part of the <algorithm> header and is used to search for the first element in a range that satisfies 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

</>
Copy
template <class InputIterator, class UnaryPredicate>
InputIterator find_if(InputIterator first, InputIterator last, UnaryPredicate pred);

Parameters of std::find_if

ParameterDescription
firstAn input iterator to the initial position in a sequence.
lastAn input iterator to the final position in a sequence (one past the last element).
predA 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 is considered a match in the context of this function. The function shall not modify its argument. This can either be a function pointer or a function object.

Return Value of std::find_if

An iterator to the first element in the range for which pred does not return false. If pred is false for all elements, the function returns last.


Exceptions for std::find_if

Throws if either pred or an operation on an iterator throws. Note that invalid parameters cause undefined behavior.


Examples for std::find_if

Example 1: Using std::find_if to Find the First Odd Number

In this example, we use std::find_if to search for the first odd number in a vector.

Program

</>
Copy
#include <iostream>
#include <vector>
#include <algorithm> // For std::find_if

bool is_odd(int n) {
    return n % 2 != 0;
}

int main() {
    std::vector<int> numbers = {10, 20, 30, 25, 40};

    auto it = std::find_if(numbers.begin(), numbers.end(), is_odd);

    if (it != numbers.end())
        std::cout << "The first odd value is " << *it << '\n';
    else
        std::cout << "No odd values found\n";

    return 0;
}

Output

The first odd value is 25

Explanation

  1. We include the necessary headers: <iostream> for input/output operations, <vector> for the std::vector container, and <algorithm> for the std::find_if function.
  2. We define a function is_odd that takes an integer and returns true if the integer is odd, and false otherwise.
  3. We create a vector numbers containing the integers 10, 20, 30, 25, and 40.
  4. We use std::find_if to search for the first odd number in the vector by passing the is_odd function as the predicate.
  5. If an odd number is found, it points to the element, and we print its value. Otherwise, we print that no odd values were found.

Example 2: Using std::find_if with a Lambda Function

This example demonstrates how to use std::find_if with a lambda function to find the first number greater than 25 in a vector.

Program

</>
Copy
#include <iostream>
#include <vector>
#include <algorithm> // For std::find_if

int main() {
    std::vector<int> numbers = {10, 20, 30, 25, 40};

    auto it = std::find_if(numbers.begin(), numbers.end(), [](int n) {
        return n > 25;
    });

    if (it != numbers.end())
        std::cout << "The first number greater than 25 is " << *it << '\n';
    else
        std::cout << "No number greater than 25 found\n";

    return 0;
}

Output

The first number greater than 25 is 30

Explanation

  1. We include the necessary headers: <iostream> for input/output operations, <vector> for the std::vector container, and <algorithm> for the std::find_if function.
  2. We create a vector numbers containing the integers 10, 20, 30, 25, and 40.
  3. We use std::find_if with a lambda function that takes an integer and returns true if the integer is greater than 25.
  4. If a number greater than 25 is found, it points to the element, and we print its value. Otherwise, we print that no such number was found.

Example 3: Using std::find_if to Find a String Starting with ‘A’

In this example, we use std::find_if to find the first string in a vector that starts with the letter ‘A’.

Program

</>
Copy
#include <iostream>
#include <vector>
#include <algorithm> // For std::find_if
#include <string>

bool starts_with_A(const std::string& s) {
    return !s.empty() && s[0] == 'A';
}

int main() {
    std::vector<std::string> names = {"Bob", "Alice", "Charlie", "Anna"};

    auto it = std::find_if(names.begin(), names.end(), starts_with_A);

    if (it != names.end())
        std::cout << "The first name starting with 'A' is " << *it << '\n';
    else
        std::cout << "No names starting with 'A' found\n";

    return 0;
}

Output

The first name starting with 'A' is Alice

Explanation

  1. We include the necessary headers: <iostream> for input/output operations, <vector> for the std::vector container, <string> for handling strings, and <algorithm> for the std::find_if function.
  2. We define a predicate function starts_with_A that takes a string and returns true if the string starts with the letter ‘A’.
  3. We create a vector names containing the strings “Bob”, “Alice”, “Charlie”, and “Anna”.
  4. We use std::find_if with the predicate starts_with_A to find the first string in the vector that starts with the letter ‘A’.
  5. If a match is found, it points to the string, and we print its value. Otherwise, we print that no such string was found.

Examples for Exceptions Thrown by std::find_if

The std::find_if 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

</>
Copy
#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 = {10, 20, -5, 25, 30};

    try {
        auto it = std::find_if(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

  1. The program defines a predicate function faulty_predicate that throws a std::runtime_error if a negative number is encountered.
  2. A vector numbers is initialized, including a negative number (-5).
  3. The std::find_if function applies the predicate to each element of the vector. When it encounters the negative number, the predicate throws an exception.
  4. 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

</>
Copy
#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 >= 0) {
            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(
            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

  1. The program defines a custom iterator FaultyIterator that throws a std::runtime_error exception after accessing two elements.
  2. An array arr is initialized with three elements.
  3. The std::find_if function searches for the first positive element in the array using the custom iterator.
  4. The iterator throws an exception during the third access, which is caught in the try-catch block.
  5. An error message is printed to indicate the exception.