# std::adjacent_find

C++ standard library is insane. There are more data structures and algorithms and utilities than someone can possible remember. If you need to something, there’s a good chance that someone already made it. And if someone already made it, there’s a good chance someone submitted a proposal to add it to the C++ standard library.

Today I want to talk about `std::adjacent_find`

, from the `<algorithm>`

library.
It returns an iterator to the first repeated element. So, if you have a list of
numbers `{1, 2, 2, 3, 3}`

, this function would return an iterator to the first
`2`

. Let’s see it in practice:

```
#include <algorithm>
#include <iostream>
#include <vector>
int main()
{
std::vector<int> numbers {1, 2, 2, 3, 3, 4, 5};
auto it = std::ranges::adjacent_find(numbers);
std::cout << *it << " " << *(it+1) << std::endl;
return 0;
}
```

I’m using `ranges`

in there, so you need a C++20 compatible compiler. To
compile it with `gcc`

: `g++ -Wall -Wextra -std=c++20 adj.cpp`

. I tested with
`g++`

10.2.0 and `clang++`

11.0.0, and both have support for it 😎.
But if you can’t (or don’t want to) use C++20, change the code to
`std::adjacent_find(numbers.begin(), numbers.end());`

This code finds the repeated elements and return an iterator to the first one. It then prints it and the next:

```
$ ./a.out
2 2
```

But we can also hack `std::adjacent_find`

with different *predicates*, and
change how we compare equality between consecutive elements. The `<functional>`

header contains some common arithmetic comparison operators, like *equal*, *not
equal*, *less*, *less equal*, etc. Using the same numbers from before, we can
find the first number that is less or equal the next one:

```
#include <algorithm>
#include <functional>
#include <iostream>
#include <vector>
int main()
{
std::vector<int> numbers {1, 2, 2, 3, 3, 4, 5};
auto it = std::ranges::adjacent_find(numbers, std::ranges::less_equal());
std::cout << *it << " " << *(it+1) << std::endl;
return 0;
}
```

This code returns `1 2`

.

Let’s see some more examples. From now on, I’ll omit the headers for brevity.

You want to find the first number that is greater the next one:

```
int main()
{
std::vector<int> numbers {1, 2, 2, 3, 3, 4, 5};
auto it = std::ranges::adjacent_find(numbers, std::ranges::greater());
if (it != numbers.end())
std::cout << *it << " " << *(it+1) << std::endl;
else
std::cout << "Found nothing" << std::endl;
return 0;
}
```

This code returns `Found nothing`

, because no two consecutive numbers in `{1, 2, 2, 3, 3, 4, 5}`

satisfies \( a > b \). When `std::adjacent_find`

does not
find anything, it returns an iterator to the end of the range.

Now you want to find the first number that does not follow the pattern \( x_{i+1} = x_i + 1 \):

```
int main()
{
std::vector<int> numbers {1, 2, 2, 3, 3, 4, 5};
auto it = std::ranges::adjacent_find(numbers,
[](int a, int b){
return a != b - 1 ;
});
if (it != numbers.end())
std::cout << *it << " " << *(it+1) << std::endl;
else
std::cout << "Found nothing" << std::endl;
return 0;
}
```

This returns, as expected, `2 2`

. This happens because `2 != 2-1`

, so the
lambda returns `true`

and the function returns the iterator to this number. By
*this number* I mean, `std::adjacent_find`

loops over the objects and compares
*this* object with the *next* one. If the sequence was `{1, 2, 3, 4, 5}`

,
`std::adjacent_find`

would return an iterator to the element after the last one
in there, that is, `numbers.end())`

.

Can you find the first pair `(a, b)`

of numbers such that
\(0.78 < a/b < 1 \)? Of course you can:

```
int main()
{
std::vector<int> numbers {1, 2, 2, 3, 3, 4, 5};
auto it = std::ranges::adjacent_find(numbers,
[](float a, float b) {
return (0.78 < a/b) && (a/b < 1);
});
if (it != numbers.end())
std::cout << *it << " " << *(it+1) << std::endl;
else
std::cout << "Found nothing" << std::endl;
return 0;
}
```

This code returns `4 5`

, because \(0.78 < 4/5 = 0.8 < 1\).

What I like about this function is that it gives to you an iterator to the
first object matching *any rule*. If have a vector/list/range of objects, and
you need to find the first one that has some relation to the next,
`std::adjacent_find`

is the way to go.