Skip to content

Find Elements In C++ Arrays With std::find_if

If you’re a beginner C++ developer, you have probably tried finding elements by writing a complicated raw loop or something similar. In this post, we look at how to use std::find_if(...) to find elements in C++ arrays, vectors, lists and maps.

Due to its flexibility, std::find_if works for all C++ collections and it’s also very easy to use.

The list below shows the contents of this post.

  1. Learning std::find_if with a video example!
  2. Creating an std::array to hold our data.
  3. Using std::find_if to get the element iterator.
    1. Explaining inputs to std::find_if.
    2. Check if element was found.
    3. Using the “found” iterator.

Video – Finding Items In C++ Collections

For demonstration purposes, I’ve posted the video below. Hopefully, you can learn by example how to find items in C++ elements in collections.

If you have any questions regarding the things taught in the video, feel free to either comment below or on the video itself. If you really want to help me out, please subscribe to the channel!

Creating The Collections To Hold Our Data

Interestingly enough, we need an actual collection (vectors, array, lists, etc) to actually find items! Therefore, we’re simply setting the context in this section by creating an array.

The code block below includes the necessary headers for this post, as well as the definitions of a custom struct and the array holding the information we will later on “find”.

#include <algorithm>
#include <array>
#include <cstdio>
#include <string>
#include <string_view>

struct Person
{
    float height;
    int age;
    std::string_view name;
};

static constexpr std::array<Person, 8> people {{
    {1.7f, 24, "matheus"},
    {1.9f, 22, "lucas"},
    {1.63f, 27, "linda"},
    {1.98f, 41, "kobe"},
    {1.82f, 41, "jake"},
    {1.65f, 37, "jena"},
    {1.78f, 57, "patrick"},
    {1.63f, 47, "drew"}
}};

To summarise, the list below explains why each header was imported.

  • algorithm contain std::find_if and other very useful functions in the C++ standard.
  • array defines the std::array collection, which we use above to store our “people” information.
  • cstdio defines puts(...), which we use for printouts later on in this post.
  • string brings the std::string collection, as well as the std::to_string(...) functions we later use in this post.
  • string_view is used to store c-strings in nice, manageable collections.

How And Why Is Our Data Being Stored In Arrays?

As you can see in the cost above, we defined the struct Person, which simply stored the height, age and name of a hypothetical person.

Following that, we create the std::array<...> people to store multiple persons information.

Long story short, there’s no particular reason for using std::array<...> , other than having my data fully available at compile time. Furthermore, as long as you have a collection of data stored in a C++ standard collection (such as vector and lists), this post will work for you.

There are certain reasons for using std::array<...> to store data in certain situations, such as converting and storing files as C++ byte arrays in your code.

Using std::find_if To Find Items In C++ Arrays / Collections

Without further ado, let’s learn how to call std::find_if. The code bock below shows a program that finds the input name in out people array.

int main(int argc, char** argv)
{
    if (argc <= 1)
    {
        return -1;
    }

    const std::string_view to_find = argv[1];

    const auto found = std::find_if(begin(people),
      end(people),
      [&](const auto& input){
        return input.name == to_find;
    });

    if (found == end(people))
    {
        // This means the item wasn't found!
        puts("Item was not in the collection");
        return -1;
    }

    // Do whatever with "found"
}

Briefly speaking, the following list explains what the code does.

  • Makes sure there’s at least one argument being passed to the program.
  • Stores the first argument as the name we’ll be using to find in the list.
  • Calls std::find_if, storing the result in found.
  • Checks whether the element was found.

Explaining The Inputs To std::find_if

As you can see, std::find_if takes three inputs: the beginning iterator, the end iterator, and the predicate (function) used to check each and every element.

If you don’t understand what “iterators” are, don’t worry too much. For the purposes of this tutorial, they are something that “points” to an element in the list, kind of like a pointer. Hence, “beginning iterator” means the first element to check. On the other hand, “end iterator” means the end of your list, or where to stop the search.

In addition, the last argument to std::find_if is a function taking an element from the list, and returning either true or false. If the function returns true, it means the element was found, if it returns false, the element was not yet found, and the search will continue.

To make it clear, the “predicate” argument to std::find_if is a callable object, meaning either a function, functor, or lambda taking one argument that is the same type stored in your list. Moreover, this predicate will be called for each element in your list, with the element being passed as the argument. This is essentially what std::find_if(...) does internally.

Checking If The Element Was Found In Arrays

As previously mentioned, std::find_if(...) returns an iterator for the collection you’re searching. If you don’t know much about iterators, notice that they can sometimes be “invalid”.

In the context of std::find_if(...) , valid iterators point to actual elements of your list, and invalid iterators don’t point to any valid elements. More specifically, invalid iterators will point to end(collection), or the end iterator of a collection (this is not the last item).

For this reason, the branch in lines 16-21 of the previous code block show how to “check” if the element was found. In other words, if the iterator returned is end(people), then the element was not found.

Using The Found Element

Now that you know how to check if the element was found, let’s actually use the information we found. Needless to say, the variable found should point to an element of the list if it’s valid.

auto const position = std::distance(begin(people), found);
puts("Found at position");
puts(std::to_string(position).c_str());
puts("Name is");
puts(found->name.data());
puts("Age is");
puts(std::to_string(found->age).c_str());
puts("Height is");
puts(std::to_string(found->height).c_str());

The code block above shows how to use the found iterator to print out all the information about the found element. Note that the syntax is pretty much the same as a pointer!

Therefore, if you add the above code to our previousmain() function, just after the found check, the program should now print the name, height and age of the found person.

As a last note, if you would like to find_if out more about the std::find(...), std::find_if(...), and std::find_if_not(...) functions provided by the algorithm header, check out the C++ documentation on the find functions!


Have I missed anything? Spotted any mistakes? Do you have suggestions or feedback? Feel free to comment below and I’ll reply as soon as possible!

Published inCPP

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *