Namespaces
Variants

std::ranges:: find_last, std::ranges:: find_last_if, std::ranges:: find_last_if_not

From cppreference.net
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy , ranges::sort , ...
Execution policies (C++17)
Non-modifying sequence operations
Batch operations
(C++17)
Search operations
Modifying sequence operations
Copy operations
(C++11)
(C++11)
Swap operations
Transformation operations
Generation operations
Removing operations
Order-changing operations
(until C++17) (C++11)
(C++20) (C++20)
Sampling operations
(C++17)

Sorting and related operations
Partitioning operations
Sorting operations
Binary search operations
(on partitioned ranges)
Set operations (on sorted ranges)
Merge operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Lexicographical comparison operations
Permutation operations
C library
Numeric operations
Operations on uninitialized memory
Constrained algorithms
All names in this menu belong to namespace std::ranges
Non-modifying sequence operations
Modifying sequence operations
Partitioning operations
Sorting operations
Binary search operations (on sorted ranges)
Set operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Permutation operations
Fold operations
Operations on uninitialized storage
Return types
(注:このHTML要素には翻訳対象のテキストコンテンツが含まれていないため、元の構造を保持したまま出力します)
定義済みヘッダー <algorithm>
呼び出しシグネチャ
(1)
template < std:: forward_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 ranges:: subrange < I >

find_last ( I first, S last, const T & value, Proj proj = { } ) ;
(C++23以降)
(C++26まで)
template < std:: forward_iterator I, std:: sentinel_for < I > S,

class Proj = std:: identity ,
class T = std :: projected_value_t < I, Proj > >
requires std:: indirect_binary_predicate
< ranges:: equal_to , std :: projected < I, Proj > , const T * >
constexpr ranges:: subrange < I >

find_last ( I first, S last, const T & value, Proj proj = { } ) ;
(C++26以降)
(2)
template < ranges:: forward_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_subrange_t < R >

find_last ( R && r, const T & value, Proj proj = { } ) ;
(C++23以降)
(C++26まで)
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 >

find_last ( R && r, const T & value, Proj proj = { } ) ;
(C++26以降)
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 >

find_last_if ( I first, S last, Pred pred, Proj proj = { } ) ;
(3) (C++23以降)
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 >

find_last_if ( R && r, Pred pred, Proj proj = { } ) ;
(4) (C++23以降)
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 >

find_last_if_not ( I first, S last, Pred pred, Proj proj = { } ) ;
(5) (C++23以降)
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 >

find_last_if_not ( R && r, Pred pred, Proj proj = { } ) ;
(6) (C++23以降)

範囲 [ first , last ) 内で特定の条件を満たす最後の要素を返します:

1) find_last value と等しい要素を検索します。
3) find_last_if は範囲 [ first , last ) 内で述語 pred true を返す最後の要素を検索します。
5) find_last_if_not は範囲 [ first , last ) 内で述語 pred false を返す最後の要素を検索します。
2,4,6) (1,3,5) と同様だが、 r をソース範囲として使用する。 ranges:: begin ( r ) first として、 ranges:: end ( r ) last として使用するかのように動作する。

このページで説明されている関数ライクな実体は、 アルゴリズム関数オブジェクト (非公式には niebloids として知られる)です。すなわち:

目次

翻訳の説明: - 「Contents」を「目次」に翻訳しました - C++関連の専門用語(Parameters, Return value, Complexity, Notes, Possible implementation, Example, See also)は原文のまま保持しました - HTMLタグ、属性、クラス名、ID、リンク先は一切変更していません - 数値や書式設定は完全に保持されています

パラメータ

first, last - 検査対象の要素の 範囲 を定義するイテレータ-センチネルペア
r - 検査対象の要素の範囲
value - 要素と比較する値
pred - 投影された要素に適用する述語
proj - 要素に適用する投影

戻り値

1,3,5) 範囲 [ first , last ) 内で E true となる最後のイテレータを i とする。
ranges::subrange<I>{i, last} を返す。 そのようなイテレータが見つからない場合は ranges::subrange<I>{last, last} を返す。
1) E bool ( std:: invoke ( proj, * i ) == value ) です。
3) E bool ( std:: invoke ( pred, std:: invoke ( proj, * i ) ) ) です。
5) E bool ( ! std:: invoke ( pred, std:: invoke ( proj, * i ) ) ) です。
2,4,6) (1,3,5) と同じですが、戻り値の型は ranges:: borrowed_subrange_t < I > です。
変更点: - "Same as" → "と同じですが" - "but the return type is" → "戻り値の型は" - 末尾のピリオドを日本語の句点「です。」に変更 - HTMLタグ、属性、 内のC++コードは一切翻訳せず保持

計算量

最大で last - first 回の述語と射影の適用。

注記

ranges::find_last , ranges::find_last_if , ranges::find_last_if_not は、 I bidirectional_iterator または(さらに良い場合) random_access_iterator をモデル化する場合、一般的な実装においてより優れた効率性を持ちます。

機能テスト マクロ 標準 機能
__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) リスト初期化 アルゴリズム用 ( 1,2 )

実装例

これらの実装は、 I forward_iterator をモデル化する場合に使用される低速なアルゴリズムのみを示しています。

**翻訳結果:** **説明:** - HTMLタグと属性はそのまま保持されています - C++関数名 `find_last_if_not` は翻訳対象外です - バージョン番号 `(5,6)` は翻訳対象外です - リンク先URLも変更されていません この翻訳では、C++の専門用語とコード関連の要素を保持しつつ、必要な部分のみを日本語化するという指示に従っています。
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
    {
        // 注: Iが単なる前方イテレータの場合、先頭から末尾までしか走査できない
        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
    {
        // 注: Iが単なるforward_iteratorの場合、先頭から末尾までしか走査できない
        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)
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
    {
        // 注: Iが単なる前方イテレータの場合、先頭から末尾までしか走査できない
        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;

#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"; };
    // コンパレータを満たす最新の要素を見つけ、pair::firstを射影する
    const auto subrange = ranges::find_last_if(list, cmp_one, &P::first);
    std::cout << "見つかった要素とそれ以降の末尾部分は:\n";
    for (P const& e : subrange)
        std::cout << '{' << std::quoted
(注:指示に従い、HTMLタグ・属性は翻訳せず、C++固有用語も翻訳していません。表示されるテキスト「std::quoted」はC++標準ライブラリの関数名であるため、そのまま保持しています)(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);
}

出力:

見つかった要素とそれ以降の末尾は:
{"one", 4} {"two", 5} {"three", 6}

関連項目

特定の範囲内で要素の最後のシーケンスを見つける
(アルゴリズム関数オブジェクト)
特定の条件を満たす最初の要素を見つける
(アルゴリズム関数オブジェクト)
要素の範囲の最初の出現を検索する
(アルゴリズム関数オブジェクト)
一方のシーケンスが他方の部分シーケンスである場合に true を返す
(アルゴリズム関数オブジェクト)
要素が半順序範囲内に存在するかどうかを判定する
(アルゴリズム関数オブジェクト)
範囲が指定された要素または部分範囲を含むかどうかをチェックする
(アルゴリズム関数オブジェクト)