C++ <algorithm> std::find_first_of

The std::find_first_of function in C++ is part of the <algorithm> header and is used to find the first occurrence of any element from one range within another range. It searches for the first element in the range [first1, last1) that matches any of the elements in the range [first2, last2), and returns an iterator to this element. If no such element is found, it returns last1.


Syntax of std::find_first_of

</>
Copy
template <class InputIterator, class ForwardIterator>
InputIterator find_first_of(InputIterator first1, InputIterator last1,
                            ForwardIterator first2, ForwardIterator last2);

template <class InputIterator, class ForwardIterator, class BinaryPredicate>
InputIterator find_first_of(InputIterator first1, InputIterator last1,
                            ForwardIterator first2, ForwardIterator last2,
                            BinaryPredicate pred);

Parameters of std::find_first_of

ParameterDescription
first1, last1Input iterators to the initial and final positions of the searched sequence. The range used is [first1, last1), which contains all the elements between first1 and last1, including the element pointed by first1 but not the element pointed by last1.
first2, last2Forward iterators to the initial and final positions of the element values to be searched for. The range used is [first2, last2). The elements in both ranges should be comparable using operator== (for the first version) or the specified predicate (for the second version).
predBinary function that accepts two elements as arguments (one from each of the two sequences, in the same order), and returns a value convertible to bool. The returned value indicates whether the elements are considered to match in the context of this function. The function shall not modify any of its arguments. This can either be a function pointer or a function object.

Return Value of std::find_first_of

An iterator to the first element in [first1, last1) that matches any of the elements in [first2, last2). If no such element is found, the function returns last1. If [first2, last2) is an empty range, the result is unspecified.


Examples for find_first_of

Example 1: Using std::find_first_of to Find the First Matching Element

In this example, we use std::find_first_of to find the first element in a vector that matches any element in another vector.

Program

</>
Copy
#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> haystack = {1, 2, 3, 4, 5};
    std::vector<int> needles = {3, 7, 9};

    auto it = std::find_first_of(haystack.begin(), haystack.end(),
                                 needles.begin(), needles.end());

    if (it != haystack.end()) {
        std::cout << "First matching element found: " << *it << '\n';
    } else {
        std::cout << "No matching element found.\n";
    }

    return 0;
}

Output

First matching element found: 3

Explanation

  1. We include the necessary headers: <iostream> for input/output operations, <vector> for the std::vector container, and <algorithm> for the std::find_first_of function.
  2. We define a vector haystack containing the integers {1, 2, 3, 4, 5}.
  3. We define another vector needles containing the integers {3, 7, 9}.
  4. We use std::find_first_of to search for the first element in haystack that matches any element in needles.
  5. If a matching element is found, it points to the element, and we print its value. Otherwise, we print that no matching element was found.

Example 2: Using std::find_first_of with a Custom Comparator

This example demonstrates how to use std::find_first_of with a custom comparator to find the first matching element between two character sequences, ignoring case sensitivity.

Program

</>
Copy
#include <iostream>
#include <vector>
#include <algorithm>
#include <cctype>

bool case_insensitive_compare(char a, char b) {
    return std::tolower(a) == std::tolower(b);
}

int main() {
    std::vector<char> haystack = {'a', 'b', 'c', 'd', 'e'};
    std::vector<char> needles = {'X', 'Y', 'C'};

    auto it = std::find_first_of(haystack.begin(), haystack.end(),
                                 needles.begin(), needles.end(),
                                 case_insensitive_compare);

    if (it != haystack.end()) {
        std::cout << "First matching element found: " << *it << '\n';
    } else {
        std::cout << "No matching element found.\n";
    }

    return 0;
}

Output

First matching element found: c

Explanation

  1. We include the necessary headers: <iostream> for input/output operations, <vector> for the std::vector container, <algorithm> for the std::find_first_of function, and <cctype> for the std::tolower function used in the custom comparator.
  2. We define a custom comparator function case_insensitive_compare that compares two characters in a case-insensitive manner by converting both to lowercase using std::tolower.
  3. We define a vector haystack containing the characters {‘a’, ‘b’, ‘c’, ‘d’, ‘e’}.
  4. We define another vector needles containing the characters {‘X’, ‘Y’, ‘C’}.
  5. We use std::find_first_of with the custom comparator to search for the first matching element in haystack that matches any element in needles, ignoring case sensitivity.
  6. If a matching element is found, it points to the element, and we print its value. Otherwise, we print that no matching element was found.

Examples for Exceptions Thrown by std::find_first_of

The std::find_first_of function can throw exceptions in the following scenarios:

  • If the comparison operation or predicate (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 a, int b) {
    if (a < 0 || b < 0) {
        throw std::runtime_error("Negative value encountered during comparison.");
    }
    return a == b;
}

int main() {
    std::vector<int> haystack = {1, -2, 3, 4, 5};
    std::vector<int> needles = {2, -3};

    try {
        auto it = std::find_first_of(haystack.begin(), haystack.end(),
                                     needles.begin(), needles.end(),
                                     faulty_predicate);

        if (it != haystack.end()) {
            std::cout << "First matching element found: " << *it << '\n';
        } else {
            std::cout << "No matching element found.\n";
        }
    } catch (const std::runtime_error& e) {
        std::cout << "Exception caught: " << e.what() << '\n';
    }

    return 0;
}

Output

Exception caught: Negative value encountered during comparison.

Explanation

  1. The program defines a predicate function faulty_predicate that throws a std::runtime_error if either value being compared is negative.
  2. The vector haystack contains both positive and negative integers.
  3. The vector needles contains integers, including a negative value.
  4. The std::find_first_of function applies the predicate to search for the first matching element between haystack and needles. When the predicate encounters a negative value, it throws an exception.
  5. The exception is caught in the try-catch block, and an error message is printed.

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::forward_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;
};

int main() {
    int haystack_arr[] = {1, 2, 3, 4, 5};
    int needles_arr[] = {2, 3};

    try {
        auto it = std::find_first_of(
            FaultyIterator(haystack_arr, true),
            FaultyIterator(haystack_arr + 5),
            needles_arr, needles_arr + 2
        );

        if (it != FaultyIterator(haystack_arr + 5)) {
            std::cout << "First matching element found: " << *it << '\n';
        } else {
            std::cout << "No matching element found.\n";
        }
    } catch (const std::runtime_error& e) {
        std::cout << "Exception caught: " << e.what() << '\n';
    }

    return 0;
}

Output

Exception caught: Iterator error during dereference.

Explanation

  1. The program defines a custom iterator FaultyIterator that throws a std::runtime_error after accessing two elements.
  2. The array haystack_arr contains five elements, and needles_arr contains two elements to search for.
  3. The std::find_first_of function uses the custom iterator to search for the first matching element between the two arrays.
  4. The iterator throws an exception during the third access, which is caught in the try-catch block, and an error message is printed.