Difference between revisions of "cpp/algorithm/ranges/find last"
m (→Notes: <br>.) |
(Possible implementation update.) |
||
(4 intermediate revisions by 3 users not shown) | |||
Line 8: | Line 8: | ||
class T, | class T, | ||
class Proj = std::identity > | class Proj = std::identity > | ||
− | requires std::indirect_binary_predicate<ranges::equal_to, std::projected<I, Proj>, | + | requires std::indirect_binary_predicate |
− | + | <ranges::equal_to, std::projected<I, Proj>, const T*> | |
constexpr ranges::subrange<I> | constexpr ranges::subrange<I> | ||
find_last( I first, S last, const T& value, Proj proj = {} ); | find_last( I first, S last, const T& value, Proj proj = {} ); | ||
Line 16: | Line 16: | ||
class Proj = std::identity, | class Proj = std::identity, | ||
class T = std::projected_value_t<I, Proj> > | class T = std::projected_value_t<I, Proj> > | ||
− | requires std::indirect_binary_predicate<ranges::equal_to, std::projected<I, Proj>, | + | requires std::indirect_binary_predicate |
− | + | <ranges::equal_to, std::projected<I, Proj>, const T*> | |
constexpr ranges::subrange<I> | constexpr ranges::subrange<I> | ||
find_last( I first, S last, const T& value, Proj proj = {} ); | find_last( I first, S last, const T& value, Proj proj = {} ); | ||
Line 25: | Line 25: | ||
class T, | class T, | ||
class Proj = std::identity > | class Proj = std::identity > | ||
− | requires std::indirect_binary_predicate<ranges::equal_to, | + | requires std::indirect_binary_predicate |
− | + | <ranges::equal_to, | |
− | + | std::projected<ranges::iterator_t<R>, Proj>, const T*> | |
constexpr ranges::borrowed_subrange_t<R> | constexpr ranges::borrowed_subrange_t<R> | ||
find_last( R&& r, const T& value, Proj proj = {} ); | find_last( R&& r, const T& value, Proj proj = {} ); | ||
Line 34: | Line 34: | ||
class Proj = std::identity, | class Proj = std::identity, | ||
class T = std::projected_value_t<iterator_t<R>, Proj> > | class T = std::projected_value_t<iterator_t<R>, Proj> > | ||
− | requires std::indirect_binary_predicate<ranges::equal_to, | + | requires std::indirect_binary_predicate |
− | + | <ranges::equal_to, | |
− | + | std::projected<ranges::iterator_t<R>, Proj>, const T*> | |
constexpr ranges::borrowed_subrange_t<R> | constexpr ranges::borrowed_subrange_t<R> | ||
find_last( R&& r, const T& value, Proj proj = {} ); | find_last( R&& r, const T& value, Proj proj = {} ); | ||
Line 48: | Line 48: | ||
}} | }} | ||
{{dcl|since=c++23|num=4|1= | {{dcl|since=c++23|num=4|1= | ||
− | template< ranges::forward_range R, class Proj = std::identity, | + | template< ranges::forward_range R, |
− | std::indirect_unary_predicate<std::projected<ranges::iterator_t<R>, Proj>> | + | class Proj = std::identity, |
− | + | std::indirect_unary_predicate | |
+ | <std::projected<ranges::iterator_t<R>, Proj>> Pred > | ||
constexpr ranges::borrowed_subrange_t<R> | constexpr ranges::borrowed_subrange_t<R> | ||
find_last_if( R&& r, Pred pred, Proj proj = {} ); | find_last_if( R&& r, Pred pred, Proj proj = {} ); | ||
Line 62: | Line 63: | ||
}} | }} | ||
{{dcl|since=c++23|num=6|1= | {{dcl|since=c++23|num=6|1= | ||
− | template< ranges::forward_range R, class Proj = std::identity, | + | template< ranges::forward_range R, |
− | std::indirect_unary_predicate<std::projected<ranges::iterator_t<R>, Proj>> | + | class Proj = std::identity, |
− | + | std::indirect_unary_predicate | |
+ | <std::projected<ranges::iterator_t<R>, Proj>> Pred > | ||
constexpr ranges::borrowed_subrange_t<R> | constexpr ranges::borrowed_subrange_t<R> | ||
find_last_if_not( R&& r, Pred pred, Proj proj = {} ); | find_last_if_not( R&& r, Pred pred, Proj proj = {} ); | ||
Line 76: | Line 78: | ||
@5@ {{tt|find_last_if_not}} searches for the last element in the range {{range|first|last}} for which predicate {{c|pred}} returns {{c|false}}. | @5@ {{tt|find_last_if_not}} searches for the last element in the range {{range|first|last}} for which predicate {{c|pred}} returns {{c|false}}. | ||
+ | |||
@2,4,6@ Same as {{v|1,3,5}}, but uses {{c|r}} as the source range, as if using {{c|ranges::begin(r)}} as {{c|first}} and {{c|ranges::end(r)}} as {{c|last}}. | @2,4,6@ Same as {{v|1,3,5}}, but uses {{c|r}} as the source range, as if using {{c|ranges::begin(r)}} as {{c|first}} and {{c|ranges::end(r)}} as {{c|last}}. | ||
Line 90: | Line 93: | ||
===Return value=== | ===Return value=== | ||
− | @1 | + | @1,3,5@ Let {{c|i}} be the last iterator in the range {{range|first|last}} for which {{c|E}} is {{c|true}}. |
+ | @@ Returns {{c|ranges::subrange<I>{i, last}<!---->}}, or {{c|ranges::subrange<I>{last, last}<!---->}} if no such iterator is found. | ||
+ | :@1@ {{c|E}} is {{c|1=bool(std::invoke(proj, *i) == value)}}. | ||
+ | :@3@ {{c|E}} is {{c|bool(std::invoke(pred, std::invoke(proj, *i)))}}. | ||
+ | :@5@ {{c|E}} is {{c|bool(!std::invoke(pred, std::invoke(proj, *i)))}}. | ||
− | @2,4,6@ Same as {{v|1 | + | @2,4,6@ Same as {{v|1,3,5}} but the return type is {{c|ranges::borrowed_subrange_t<I>}}. |
===Complexity=== | ===Complexity=== | ||
Line 98: | Line 105: | ||
===Notes=== | ===Notes=== | ||
− | {{tt|ranges::find_last}}, {{tt|ranges::find_last_if}}, {{tt|ranges::find_last_if_not}} have better efficiency on common implementations if {{ | + | {{tt|ranges::find_last}}, {{tt|ranges::find_last_if}}, {{tt|ranges::find_last_if_not}} have better efficiency on common implementations if {{tt|I}} models {{lconcept|bidirectional_iterator}} or (better) {{lconcept|random_access_iterator}}. |
{{ftm begin}} | {{ftm begin}} | ||
{{ftm|std=C++23|value=202207L|__cpp_lib_ranges_find_last|{{tt|ranges::find_last}},<br>{{tt|ranges::find_last_if}},<br>{{tt|ranges::find_last_if_not}}}} | {{ftm|std=C++23|value=202207L|__cpp_lib_ranges_find_last|{{tt|ranges::find_last}},<br>{{tt|ranges::find_last_if}},<br>{{tt|ranges::find_last_if_not}}}} | ||
− | {{ftm|__cpp_lib_algorithm_default_value_type|value= | + | {{ftm|__cpp_lib_algorithm_default_value_type|value=202403L|std=C++26|[[cpp/language/list initialization|List-initialization]] for algorithms {{vl|1,2}}}} |
{{ftm end}} | {{ftm end}} | ||
Line 108: | Line 115: | ||
These implementations only show the slower algorithm used when {{c|I}} models {{lconcept|forward_iterator}}. | These implementations only show the slower algorithm used when {{c|I}} models {{lconcept|forward_iterator}}. | ||
{{eq impl | {{eq impl | ||
− | |title1=find_last (1 | + | |title1=find_last (1,2)|ver1=1|1= |
struct find_last_fn | struct find_last_fn | ||
{ | { | ||
Line 114: | Line 121: | ||
class Proj = std::identity, | class Proj = std::identity, | ||
class T = std::projected_value_t<iterator_t<R>, Proj>> | class T = std::projected_value_t<iterator_t<R>, Proj>> | ||
− | requires std::indirect_binary_predicate<ranges::equal_to, std::projected<I, Proj>, | + | requires std::indirect_binary_predicate |
− | + | <ranges::equal_to, std::projected<I, Proj>, const T*> | |
constexpr ranges::subrange<I> | constexpr ranges::subrange<I> | ||
operator()(I first, S last, const T &value, Proj proj = {}) const | operator()(I first, S last, const T &value, Proj proj = {}) const | ||
{ | { | ||
// Note: if I is mere forward_iterator, we may only go from begin to end. | // Note: if I is mere forward_iterator, we may only go from begin to end. | ||
− | I found | + | std::optional<I> found; |
for (; first != last; ++first) | for (; first != last; ++first) | ||
if (std::invoke(proj, *first) == value) | if (std::invoke(proj, *first) == value) | ||
found = first; | found = first; | ||
− | + | ||
− | if (found | + | if (!found) |
return {first, first}; | return {first, first}; | ||
− | + | ||
− | return {found, std::ranges::next(found, last)}; | + | return {*found, std::ranges::next(*found, last)}; |
} | } | ||
− | + | ||
template<ranges::forward_range R, | template<ranges::forward_range R, | ||
class Proj = std::identity, | class Proj = std::identity, | ||
class T = std::projected_value_t<iterator_t<R>, Proj>> | class T = std::projected_value_t<iterator_t<R>, Proj>> | ||
− | requires std::indirect_binary_predicate<ranges::equal_to, | + | requires std::indirect_binary_predicate |
− | + | <ranges::equal_to, | |
− | + | std::projected<ranges::iterator_t<R>, Proj>, const T*> | |
constexpr ranges::borrowed_subrange_t<R> | constexpr ranges::borrowed_subrange_t<R> | ||
operator()(R&& r, const T &value, Proj proj = {}) const | operator()(R&& r, const T &value, Proj proj = {}) const | ||
Line 145: | Line 152: | ||
inline constexpr find_last_fn find_last; | inline constexpr find_last_fn find_last; | ||
− | |title2=find_last_if (3 | + | |title2=find_last_if (3,4)|ver2=3|2= |
struct find_last_if_fn | struct find_last_if_fn | ||
{ | { | ||
Line 155: | Line 162: | ||
{ | { | ||
// Note: if I is mere forward_iterator, we may only go from begin to end. | // Note: if I is mere forward_iterator, we may only go from begin to end. | ||
− | I found | + | std::optional<I> found; |
for (; first != last; ++first) | for (; first != last; ++first) | ||
if (std::invoke(pred, std::invoke(proj, *first))) | if (std::invoke(pred, std::invoke(proj, *first))) | ||
found = first; | found = first; | ||
− | + | ||
− | if (found | + | if (!found) |
return {first, first}; | return {first, first}; | ||
− | + | ||
− | return {found, std::ranges::next(found, last)}; | + | return {*found, std::ranges::next(*found, last)}; |
} | } | ||
− | + | ||
template<ranges::forward_range R, class Proj = std::identity, | template<ranges::forward_range R, class Proj = std::identity, | ||
− | std::indirect_unary_predicate<std::projected<ranges::iterator_t<R>, Proj>> | + | std::indirect_unary_predicate |
− | + | <std::projected<ranges::iterator_t<R>, Proj>> Pred> | |
constexpr ranges::borrowed_subrange_t<R> | constexpr ranges::borrowed_subrange_t<R> | ||
operator()(R&& r, Pred pred, Proj proj = {}) const | operator()(R&& r, Pred pred, Proj proj = {}) const | ||
Line 178: | Line 185: | ||
inline constexpr find_last_if_fn find_last_if; | inline constexpr find_last_if_fn find_last_if; | ||
− | |title3=find_last_if_not (5 | + | |title3=find_last_if_not (5,6)|ver3=5|3= |
struct find_last_if_not_fn | struct find_last_if_not_fn | ||
{ | { | ||
Line 188: | Line 195: | ||
{ | { | ||
// Note: if I is mere forward_iterator, we may only go from begin to end. | // Note: if I is mere forward_iterator, we may only go from begin to end. | ||
− | I found | + | std::optional<I> found; |
for (; first != last; ++first) | for (; first != last; ++first) | ||
if (!std::invoke(pred, std::invoke(proj, *first))) | if (!std::invoke(pred, std::invoke(proj, *first))) | ||
found = first; | found = first; | ||
− | + | ||
− | if (found | + | if (!found) |
return {first, first}; | return {first, first}; | ||
− | + | ||
− | return {found, std::ranges::next(found, last)}; | + | return {*found, std::ranges::next(*found, last)}; |
} | } | ||
− | + | ||
template<ranges::forward_range R, class Proj = std::identity, | template<ranges::forward_range R, class Proj = std::identity, | ||
− | std::indirect_unary_predicate<std::projected<ranges::iterator_t<R>, Proj>> | + | std::indirect_unary_predicate |
− | + | <std::projected<ranges::iterator_t<R>, Proj>> Pred> | |
constexpr ranges::borrowed_subrange_t<R> | constexpr ranges::borrowed_subrange_t<R> | ||
operator()(R&& r, Pred pred, Proj proj = {}) const | operator()(R&& r, Pred pred, Proj proj = {}) const | ||
Line 226: | Line 233: | ||
{ | { | ||
namespace ranges = std::ranges; | namespace ranges = std::ranges; | ||
− | + | ||
constexpr static auto v = {1, 2, 3, 1, 2, 3, 1, 2}; | constexpr static auto v = {1, 2, 3, 1, 2, 3, 1, 2}; | ||
− | + | ||
{ | { | ||
constexpr auto i1 = ranges::find_last(v.begin(), v.end(), 3); | constexpr auto i1 = ranges::find_last(v.begin(), v.end(), 3); | ||
Line 241: | Line 248: | ||
static_assert(i2.begin() == v.end()); | static_assert(i2.begin() == v.end()); | ||
} | } | ||
− | + | ||
auto abs = [](int x) { return x < 0 ? -x : x; }; | auto abs = [](int x) { return x < 0 ? -x : x; }; | ||
− | + | ||
{ | { | ||
auto pred = [](int x) { return x == 3; }; | auto pred = [](int x) { return x == 3; }; | ||
Line 258: | Line 265: | ||
static_assert(i2.begin() == v.end()); | static_assert(i2.begin() == v.end()); | ||
} | } | ||
− | + | ||
{ | { | ||
auto pred = [](int x) { return x == 1 or x == 2; }; | auto pred = [](int x) { return x == 1 or x == 2; }; | ||
Line 273: | Line 280: | ||
static_assert(i2.begin() == v.end()); | static_assert(i2.begin() == v.end()); | ||
} | } | ||
− | + | ||
using P = std::pair<std::string_view, int>; | using P = std::pair<std::string_view, int>; | ||
std::forward_list<P> list | std::forward_list<P> list | ||
Line 281: | Line 288: | ||
}; | }; | ||
auto cmp_one = [](const std::string_view &s) { return s == "one"; }; | auto cmp_one = [](const std::string_view &s) { return s == "one"; }; | ||
− | + | ||
// find latest element that satisfy the comparator, and projecting pair::first | // find latest element that satisfy the comparator, and projecting pair::first | ||
const auto subrange = ranges::find_last_if(list, cmp_one, &P::first); | const auto subrange = ranges::find_last_if(list, cmp_one, &P::first); | ||
− | + | ||
− | + | std::cout << "The found element and the tail after it are:\n"; | |
for (P const& e : subrange) | for (P const& e : subrange) | ||
std::cout << '{' << std::quoted(e.first) << ", " << e.second << "} "; | std::cout << '{' << std::quoted(e.first) << ", " << e.second << "} "; | ||
std::cout << '\n'; | std::cout << '\n'; | ||
− | + | ||
#if __cpp_lib_algorithm_default_value_type | #if __cpp_lib_algorithm_default_value_type | ||
const auto i3 = ranges::find_last(list, {"three", 3}); // (2) C++26 | const auto i3 = ranges::find_last(list, {"three", 3}); // (2) C++26 | ||
Line 298: | Line 305: | ||
} | } | ||
|output= | |output= | ||
+ | The found element and the tail after it are: | ||
{"one", 4} {"two", 5} {"three", 6} | {"one", 4} {"two", 5} {"three", 6} | ||
}} | }} |
Latest revision as of 18:41, 16 July 2024
Defined in header <algorithm>
|
||
Call signature |
||
(1) | ||
template< std::forward_iterator I, std::sentinel_for<I> S, class T, |
(since C++23) (until C++26) |
|
template< std::forward_iterator I, std::sentinel_for<I> S, class Proj = std::identity, |
(since C++26) | |
(2) | ||
template< ranges::forward_range R, class T, |
(since C++23) (until C++26) |
|
template< ranges::forward_range R, class Proj = std::identity, |
(since C++26) | |
template< std::forward_iterator I, std::sentinel_for<I> S, class Proj = std::identity, |
(3) | (since C++23) |
template< ranges::forward_range R, class Proj = std::identity, |
(4) | (since C++23) |
template< std::forward_iterator I, std::sentinel_for<I> S, class Proj = std::identity, |
(5) | (since C++23) |
template< ranges::forward_range R, class Proj = std::identity, |
(6) | (since C++23) |
Returns the last element in the range [
first,
last)
that satisfies specific criteria:
find_last
searches for an element equal to value.find_last_if
searches for the last element in the range [
first,
last)
for which predicate pred returns true.find_last_if_not
searches for the last element in the range [
first,
last)
for which predicate pred returns false.The function-like entities described on this page are 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.
In practice, they may be implemented as function objects, or with special compiler extensions.
Contents |
[edit] Parameters
first, last | - | the range of elements to examine |
r | - | the range of the elements to examine |
value | - | value to compare the elements to |
pred | - | predicate to apply to the projected elements |
proj | - | projection to apply to the elements |
[edit] Return value
[
first,
last)
for which E is true.[edit] Complexity
At most last - first applications of the predicate and projection.
[edit] Notes
ranges::find_last
, ranges::find_last_if
, ranges::find_last_if_not
have better efficiency on common implementations if I
models bidirectional_iterator
or (better) random_access_iterator
.
Feature-test macro | Value | Std | Feature |
---|---|---|---|
__cpp_lib_ranges_find_last |
202207L | (C++23) | ranges::find_last ,ranges::find_last_if ,ranges::find_last_if_not
|
__cpp_lib_algorithm_default_value_type |
202403L | (C++26) | List-initialization for algorithms (1,2) |
[edit] Possible implementation
These implementations only show the slower algorithm used when I models forward_iterator
.
find_last (1,2) |
---|
struct find_last_fn { template<std::forward_iterator I, std::sentinel_for<I> S, class Proj = std::identity, class T = std::projected_value_t<iterator_t<R>, Proj>> requires std::indirect_binary_predicate <ranges::equal_to, std::projected<I, Proj>, const T*> constexpr ranges::subrange<I> operator()(I first, S last, const T &value, Proj proj = {}) const { // Note: if I is mere forward_iterator, we may only go from begin to end. std::optional<I> found; for (; first != last; ++first) if (std::invoke(proj, *first) == value) found = first; if (!found) return {first, first}; return {*found, std::ranges::next(*found, last)}; } template<ranges::forward_range R, class Proj = std::identity, class T = std::projected_value_t<iterator_t<R>, Proj>> requires std::indirect_binary_predicate <ranges::equal_to, std::projected<ranges::iterator_t<R>, Proj>, const T*> constexpr ranges::borrowed_subrange_t<R> operator()(R&& r, const T &value, Proj proj = {}) const { return this->operator()(ranges::begin(r), ranges::end(r), value, std::ref(proj)); } }; inline constexpr find_last_fn find_last; |
find_last_if (3,4) |
struct find_last_if_fn { template<std::forward_iterator I, std::sentinel_for<I> S, class Proj = std::identity, std::indirect_unary_predicate<std::projected<I, Proj>> Pred> constexpr ranges::subrange<I> operator()(I first, S last, Pred pred, Proj proj = {}) const { // Note: if I is mere forward_iterator, we may only go from begin to end. std::optional<I> found; for (; first != last; ++first) if (std::invoke(pred, std::invoke(proj, *first))) found = first; if (!found) return {first, first}; return {*found, std::ranges::next(*found, last)}; } template<ranges::forward_range R, class Proj = std::identity, std::indirect_unary_predicate <std::projected<ranges::iterator_t<R>, Proj>> Pred> constexpr ranges::borrowed_subrange_t<R> operator()(R&& r, Pred pred, Proj proj = {}) const { return this->operator()(ranges::begin(r), ranges::end(r), std::ref(pred), std::ref(proj)); } }; inline constexpr find_last_if_fn find_last_if; |
find_last_if_not (5,6) |
struct find_last_if_not_fn { template<std::forward_iterator I, std::sentinel_for<I> S, class Proj = std::identity, std::indirect_unary_predicate<std::projected<I, Proj>> Pred> constexpr ranges::subrange<I> operator()(I first, S last, Pred pred, Proj proj = {}) const { // Note: if I is mere forward_iterator, we may only go from begin to end. std::optional<I> found; for (; first != last; ++first) if (!std::invoke(pred, std::invoke(proj, *first))) found = first; if (!found) return {first, first}; return {*found, std::ranges::next(*found, last)}; } template<ranges::forward_range R, class Proj = std::identity, std::indirect_unary_predicate <std::projected<ranges::iterator_t<R>, Proj>> Pred> constexpr ranges::borrowed_subrange_t<R> operator()(R&& r, Pred pred, Proj proj = {}) const { return this->operator()(ranges::begin(r), ranges::end(r), std::ref(pred), std::ref(proj)); } }; inline constexpr find_last_if_not_fn find_last_if_not; |
[edit] Example
#include <algorithm> #include <cassert> #include <forward_list> #include <iomanip> #include <iostream> #include <string_view> int main() { namespace ranges = std::ranges; constexpr static auto v = {1, 2, 3, 1, 2, 3, 1, 2}; { constexpr auto i1 = ranges::find_last(v.begin(), v.end(), 3); constexpr auto i2 = ranges::find_last(v, 3); static_assert(ranges::distance(v.begin(), i1.begin()) == 5); static_assert(ranges::distance(v.begin(), i2.begin()) == 5); } { constexpr auto i1 = ranges::find_last(v.begin(), v.end(), -3); constexpr auto i2 = ranges::find_last(v, -3); static_assert(i1.begin() == v.end()); static_assert(i2.begin() == v.end()); } auto abs = [](int x) { return x < 0 ? -x : x; }; { auto pred = [](int x) { return x == 3; }; constexpr auto i1 = ranges::find_last_if(v.begin(), v.end(), pred, abs); constexpr auto i2 = ranges::find_last_if(v, pred, abs); static_assert(ranges::distance(v.begin(), i1.begin()) == 5); static_assert(ranges::distance(v.begin(), i2.begin()) == 5); } { auto pred = [](int x) { return x == -3; }; constexpr auto i1 = ranges::find_last_if(v.begin(), v.end(), pred, abs); constexpr auto i2 = ranges::find_last_if(v, pred, abs); static_assert(i1.begin() == v.end()); static_assert(i2.begin() == v.end()); } { auto pred = [](int x) { return x == 1 or x == 2; }; constexpr auto i1 = ranges::find_last_if_not(v.begin(), v.end(), pred, abs); constexpr auto i2 = ranges::find_last_if_not(v, pred, abs); static_assert(ranges::distance(v.begin(), i1.begin()) == 5); static_assert(ranges::distance(v.begin(), i2.begin()) == 5); } { auto pred = [](int x) { return x == 1 or x == 2 or x == 3; }; constexpr auto i1 = ranges::find_last_if_not(v.begin(), v.end(), pred, abs); constexpr auto i2 = ranges::find_last_if_not(v, pred, abs); static_assert(i1.begin() == v.end()); static_assert(i2.begin() == v.end()); } using P = std::pair<std::string_view, int>; std::forward_list<P> list { {"one", 1}, {"two", 2}, {"three", 3}, {"one", 4}, {"two", 5}, {"three", 6}, }; auto cmp_one = [](const std::string_view &s) { return s == "one"; }; // find latest element that satisfy the comparator, and projecting pair::first const auto subrange = ranges::find_last_if(list, cmp_one, &P::first); std::cout << "The found element and the tail after it are:\n"; for (P const& e : subrange) std::cout << '{' << std::quoted(e.first) << ", " << e.second << "} "; std::cout << '\n'; #if __cpp_lib_algorithm_default_value_type const auto i3 = ranges::find_last(list, {"three", 3}); // (2) C++26 #else const auto i3 = ranges::find_last(list, P{"three", 3}); // (2) C++23 #endif assert(i3.begin()->first == "three" && i3.begin()->second == 3); }
Output:
The found element and the tail after it are: {"one", 4} {"two", 5} {"three", 6}
[edit] See also
(C++20) |
finds the last sequence of elements in a certain range (niebloid) |
(C++20)(C++20)(C++20) |
finds the first element satisfying specific criteria (niebloid) |
(C++20) |
searches for the first occurrence of a range of elements (niebloid) |
(C++20) |
returns true if one sequence is a subsequence of another (niebloid) |
(C++20) |
determines if an element exists in a partially-ordered range (niebloid) |
(C++23)(C++23) |
checks if the range contains the given element or subrange (niebloid) |