Skip to main content

std::ranges::find() algorithm

// (1)
constexpr I
find( I first, S last, const T& value, Proj proj = {} );

// (2)
constexpr ranges::borrowed_iterator_t<R>
find( R&& r, const T& value, Proj proj = {} );

The type of arguments are generic and have the following constraints:

  • I - std::input_iterator
  • S - std::sentinel_for<I>
  • T - (none)
  • Proj - (none)
  • (2) - R - std::ranges::input_range

The Proj template argument has a default type of std::identity for all overloads.

Additionally, each overload has the following constraints:

  • (1) - indirect_binary_predicate<ranges::equal_to, projected<I, Proj>, const T*>>
  • (2) - indirect_binary_predicate<ranges::equal_to, projected<ranges::iterator_t<R>, Proj>, const T*>

(The std:: namespace was ommitted here for readability)

Returns an iterator to the first element in the range satisfiying specific criteria (or last iterator if there is no such iterator):

  • (1) Searches for an element equal to value (using operator==)

  • (2) Same as (1), but uses r as the source range, as if using ranges::begin(r) as first and ranges::end(r) as last.

The function-like entities described on this page are niebloids.

Parameters

first
last

The range of elements to apply the function to.

r

The range of elements to apply the function to.

value

Value to compare the elements to.

proj

Projection to apply to the elements.

Return value

Iterator to the first element satisfying the condition or iterator equal to last if no such element is found.

Complexity

Exactly last - first applications of the predicate and projection.

Exceptions

(none)

Possible implementation

find(1)
struct find_fn
{
template<std::input_iterator I, std::sentinel_for<I> S,
class T, class Proj = std::identity>
requires std::indirect_binary_predicate<
ranges::equal_to, std::projected<I, Proj>, const T*>
constexpr I operator()(I first, S last, const T& value, Proj proj = {}) const
{
for (; first != last; ++first)
if (std::invoke(proj, *first) == value)
return first;
return first;
}

template<ranges::input_range R, class T, class Proj = std::identity>
requires std::indirect_binary_predicate<ranges::equal_to,
std::projected<ranges::iterator_t<R>, Proj>, const T*>
constexpr ranges::borrowed_iterator_t<R>
operator()(R&& r, const T& value, Proj proj = {}) const
{
return (*this)(ranges::begin(r), ranges::end(r), value, std::ref(proj));
}
};

inline constexpr find_fn find;

Examples

Main.cpp
#include <algorithm>
#include <iostream>
#include <iterator>

int main()
{
namespace ranges = std::ranges;

const int n1 = 3;
const int n2 = 5;
const auto v = {4, 1, 3, 2};

if (ranges::find(v, n1) != v.end())
std::cout << "v contains: " << n1 << '\n';
else
std::cout << "v does not contain: " << n1 << '\n';

if (ranges::find(v.begin(), v.end(), n2) != v.end())
std::cout << "v contains: " << n2 << '\n';
else
std::cout << "v does not contain: " << n2 << '\n';

auto is_even = [](int x) { return x % 2 == 0; };

if (auto result = ranges::find_if(v.begin(), v.end(), is_even); result != v.end())
std::cout << "First even element in v: " << *result << '\n';
else
std::cout << "No even elements in v\n";

if (auto result = ranges::find_if_not(v, is_even); result != v.end())
std::cout << "First odd element in v: " << *result << '\n';
else
std::cout << "No odd elements in v\n";

auto divides_13 = [](int x) { return x % 13 == 0; };

if (auto result = ranges::find_if(v, divides_13); result != v.end())
std::cout << "First element divisible by 13 in v: " << *result << '\n';
else
std::cout << "No elements in v are divisible by 13\n";

if (auto result = ranges::find_if_not(v.begin(), v.end(), divides_13);
result != v.end())
std::cout << "First element indivisible by 13 in v: " << *result << '\n';
else
std::cout << "All elements in v are divisible by 13\n";
}
Output
v contains: 3
v does not contain: 5
First even element in v: 4
First odd element in v: 1
No elements in v are divisible by 13
First element indivisible by 13 in v: 4
This article originates from this CppReference page. It was likely altered for improvements or editors' preference. Click "Edit this page" to see all changes made to this document.
Hover to see the original license.

std::ranges::find() algorithm

// (1)
constexpr I
find( I first, S last, const T& value, Proj proj = {} );

// (2)
constexpr ranges::borrowed_iterator_t<R>
find( R&& r, const T& value, Proj proj = {} );

The type of arguments are generic and have the following constraints:

  • I - std::input_iterator
  • S - std::sentinel_for<I>
  • T - (none)
  • Proj - (none)
  • (2) - R - std::ranges::input_range

The Proj template argument has a default type of std::identity for all overloads.

Additionally, each overload has the following constraints:

  • (1) - indirect_binary_predicate<ranges::equal_to, projected<I, Proj>, const T*>>
  • (2) - indirect_binary_predicate<ranges::equal_to, projected<ranges::iterator_t<R>, Proj>, const T*>

(The std:: namespace was ommitted here for readability)

Returns an iterator to the first element in the range satisfiying specific criteria (or last iterator if there is no such iterator):

  • (1) Searches for an element equal to value (using operator==)

  • (2) Same as (1), but uses r as the source range, as if using ranges::begin(r) as first and ranges::end(r) as last.

The function-like entities described on this page are niebloids.

Parameters

first
last

The range of elements to apply the function to.

r

The range of elements to apply the function to.

value

Value to compare the elements to.

proj

Projection to apply to the elements.

Return value

Iterator to the first element satisfying the condition or iterator equal to last if no such element is found.

Complexity

Exactly last - first applications of the predicate and projection.

Exceptions

(none)

Possible implementation

find(1)
struct find_fn
{
template<std::input_iterator I, std::sentinel_for<I> S,
class T, class Proj = std::identity>
requires std::indirect_binary_predicate<
ranges::equal_to, std::projected<I, Proj>, const T*>
constexpr I operator()(I first, S last, const T& value, Proj proj = {}) const
{
for (; first != last; ++first)
if (std::invoke(proj, *first) == value)
return first;
return first;
}

template<ranges::input_range R, class T, class Proj = std::identity>
requires std::indirect_binary_predicate<ranges::equal_to,
std::projected<ranges::iterator_t<R>, Proj>, const T*>
constexpr ranges::borrowed_iterator_t<R>
operator()(R&& r, const T& value, Proj proj = {}) const
{
return (*this)(ranges::begin(r), ranges::end(r), value, std::ref(proj));
}
};

inline constexpr find_fn find;

Examples

Main.cpp
#include <algorithm>
#include <iostream>
#include <iterator>

int main()
{
namespace ranges = std::ranges;

const int n1 = 3;
const int n2 = 5;
const auto v = {4, 1, 3, 2};

if (ranges::find(v, n1) != v.end())
std::cout << "v contains: " << n1 << '\n';
else
std::cout << "v does not contain: " << n1 << '\n';

if (ranges::find(v.begin(), v.end(), n2) != v.end())
std::cout << "v contains: " << n2 << '\n';
else
std::cout << "v does not contain: " << n2 << '\n';

auto is_even = [](int x) { return x % 2 == 0; };

if (auto result = ranges::find_if(v.begin(), v.end(), is_even); result != v.end())
std::cout << "First even element in v: " << *result << '\n';
else
std::cout << "No even elements in v\n";

if (auto result = ranges::find_if_not(v, is_even); result != v.end())
std::cout << "First odd element in v: " << *result << '\n';
else
std::cout << "No odd elements in v\n";

auto divides_13 = [](int x) { return x % 13 == 0; };

if (auto result = ranges::find_if(v, divides_13); result != v.end())
std::cout << "First element divisible by 13 in v: " << *result << '\n';
else
std::cout << "No elements in v are divisible by 13\n";

if (auto result = ranges::find_if_not(v.begin(), v.end(), divides_13);
result != v.end())
std::cout << "First element indivisible by 13 in v: " << *result << '\n';
else
std::cout << "All elements in v are divisible by 13\n";
}
Output
v contains: 3
v does not contain: 5
First even element in v: 4
First odd element in v: 1
No elements in v are divisible by 13
First element indivisible by 13 in v: 4
This article originates from this CppReference page. It was likely altered for improvements or editors' preference. Click "Edit this page" to see all changes made to this document.
Hover to see the original license.