std::ranges::find_first_of
Defined in header <algorithm> | ||
Call signature | ||
template<std::input_iterator I1, std::sentinel_for<I1> S1, std::forward_iterator I2, std::sentinel_for<I2> S2, | (1) | (since C++20) |
template<ranges::input_range R1, ranges::forward_range R2, class Pred =ranges::equal_to, | (2) | (since C++20) |
[
first1,
last1)
for any of the elements in the range [
first2,
last2)
, after projecting the ranges with proj1 and proj2 respectively. The projected elements are compared using the binary predicate pred.The function-like entities described on this page are algorithm function objects (informally known as niebloids), that is:
- Explicit template argument lists cannot be specified when calling any of them.
- None of them are visible to argument-dependent lookup.
- When any of them are found by normal unqualified lookup as the name to the left of the function-call operator, argument-dependent lookup is inhibited.
Contents |
[edit]Parameters
first1, last1 | - | the iterator-sentinel pair defining the range of elements to examine (aka haystack) |
first2, last2 | - | the iterator-sentinel pair defining the range of elements to search for (aka needles) |
r1 | - | the range of elements to examine (aka haystack) |
r2 | - | the range of elements to search for (aka needles) |
pred | - | binary predicate to compare the elements |
proj1 | - | projection to apply to the elements in the first range |
proj2 | - | projection to apply to the elements in the second range |
[edit]Return value
Iterator to the first element in the range [
first1,
last1)
that is equal to an element from the range [
first2,
last2)
after projection. If no such element is found, an iterator comparing equal to last1 is returned.
[edit]Complexity
At most S * N applications of the predicate and each projection, where
(1)S =ranges::distance(first2, last2) and N =ranges::distance(first1, last1);
(2)S =ranges::distance(r2) and N =ranges::distance(r1).
[edit]Possible implementation
struct find_first_of_fn {template<std::input_iterator I1, std::sentinel_for<I1> S1, std::forward_iterator I2, std::sentinel_for<I2> S2, class Pred =ranges::equal_to, class Proj1 =std::identity, class Proj2 =std::identity> requires std::indirectly_comparable<I1, I2, Pred, Proj1, Proj2>constexpr I1 operator()(I1 first1, S1 last1, I2 first2, S2 last2, Pred pred ={}, Proj1 proj1 ={}, Proj2 proj2 ={})const{for(; first1 != last1;++first1)for(auto i = first2; i != last2;++i)if(std::invoke(pred, std::invoke(proj1, *first1), std::invoke(proj2, *i)))return first1;return first1;} template<ranges::input_range R1, ranges::forward_range R2, class Pred =ranges::equal_to, class Proj1 =std::identity, class Proj2 =std::identity> requires std::indirectly_comparable<ranges::iterator_t<R1>, ranges::iterator_t<R2>, Pred, Proj1, Proj2>constexprranges::borrowed_iterator_t<R1> operator()(R1&& r1, R2&& r2, Pred pred ={}, Proj1 proj1 ={}, Proj2 proj2 ={})const{return(*this)(ranges::begin(r1), ranges::end(r1), ranges::begin(r2), ranges::end(r2), std::move(pred), std::move(proj1), std::move(proj2));}}; inlineconstexpr find_first_of_fn find_first_of {}; |
[edit]Example
#include <algorithm>#include <iostream>#include <iterator> int main(){namespace rng = std::ranges; constexprstaticauto haystack ={1, 2, 3, 4};constexprstaticauto needles ={0, 3, 4, 3}; constexprauto found1 = rng::find_first_of(haystack.begin(), haystack.end(), needles.begin(), needles.end()); static_assert(std::distance(haystack.begin(), found1)==2); constexprauto found2 = rng::find_first_of(haystack, needles); static_assert(std::distance(haystack.begin(), found2)==2); constexprstaticauto negatives ={-6, -3, -4, -3};constexprauto not_found = rng::find_first_of(haystack, negatives); static_assert(not_found == haystack.end()); constexprauto found3 = rng::find_first_of(haystack, negatives, [](int x, int y){return x ==-y;});// uses a binary comparator static_assert(std::distance(haystack.begin(), found3)==2); struct P {int x, y;};constexprstaticauto p1 ={P{1, -1}, P{2, -2}, P{3, -3}, P{4, -4}};constexprstaticauto p2 ={P{5, -5}, P{6, -3}, P{7, -5}, P{8, -3}}; // Compare only P::y data members by projecting them:constauto found4 = rng::find_first_of(p1, p2, {}, &P::y, &P::y);std::cout<<"First equivalent element {"<< found4->x <<", "<< found4->y <<"} was found at position "<<std::distance(p1.begin(), found4)<<".\n";}
Output:
First equivalent element {3, -3} was found at position 2.
[edit]See also
searches for any one of a set of elements (function template) | |
(C++20) | finds the first two adjacent items that are equal (or satisfy a given predicate) (algorithm function object) |
(C++20)(C++20)(C++20) | finds the first element satisfying specific criteria (algorithm function object) |
(C++20) | finds the last sequence of elements in a certain range (algorithm function object) |
(C++20) | searches for the first occurrence of a range of elements (algorithm function object) |
(C++20) | searches for the first occurrence of a number consecutive copies of an element in a range (algorithm function object) |