Namespaces
Variants

std::find_first_of

ja.cppreference.net より
 
 
アルゴリズムライブラリ
制約付きアルゴリズムとレンジのアルゴリズム (C++20)
制約付きアルゴリズム、例:ranges::copy, ranges::sort, ...
ソートと関連操作
分割操作
(C++11)    

ソート操作
二分探索操作
(分割された範囲に対して)
集合操作 (ソート済み範囲に対して)
マージ操作 (ソート済み範囲に対して)
ヒープ操作
最小値/最大値操作
(C++11)
(C++17)
辞書順比較操作
順列操作


 
ヘッダ <algorithm>
template< class InputIt, class ForwardIt >
InputIt find_first_of( InputIt first1, InputIt last1,
                       ForwardIt first2, ForwardIt last2 );
で定義 (1) (constexpr C++20以降)
template< class InputIt, class ForwardIt, class BinaryPred >
InputIt find_first_of( InputIt first1, InputIt last1,
                       ForwardIt first2, ForwardIt last2,
                       BinaryPred p );
(2) (constexpr C++20以降)
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2 >
ForwardIt1 find_first_of( ExecutionPolicy&& policy,
                          ForwardIt1 first1, ForwardIt1 last1,
                          ForwardIt2 first2, ForwardIt2 last2 );
(3) (C++17以降)
template< class ExecutionPolicy,
          class ForwardIt1, class ForwardIt2, class BinaryPred >
ForwardIt1 find_first_of( ExecutionPolicy&& policy,
                          ForwardIt1 first1, ForwardIt last1,
                          ForwardIt2 first2, ForwardIt2 last2,
                          BinaryPred p );
(4) (C++17以降)

ソース範囲 [first1, last1) 内から、ターゲット範囲 [first2, last2) 内のいずれかの要素を検索します。

1) 要素の比較は operator== を使用します。
2) 要素の比較は、指定された二項述語 p を使用します。
3,4) (1,2) と同じですが、policy に従って実行されます。
これらのオーバーロードは、次の式の値が true である場合にのみオーバーロード解決に参加します。

std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>

(C++20まで)

std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>

(C++20以降)

引数

first1, last1 - ソース範囲を定義するイテレータのペア範囲
first2, last2 - ターゲット範囲を定義するイテレータのペア範囲
p - 要素が等しいと扱われるべき場合に true を返す二項述語。

述語関数のシグネチャは以下と等価であるべきです:

bool pred(const Type1 &a, const Type2 &b);

シグネチャに const & は必要ありませんが、関数は渡されたオブジェクトを変更してはならず、型 (const の場合もある) Type1 と Type2 のすべての値を 値カテゴリに関係なく受理できなければなりません(したがって、Type1 & は許可されません。また、Type1 も、Type1 ムーブがコピーと等価である場合を除き許可されません(C++11以降))。
型 Type1 と Type2 は、型 ForwardIt1 と ForwardIt2 のオブジェクトを逆参照してから、それぞれ Type1 と Type2 に暗黙的に変換できるようにする必要があります。 ​

policy - 使用する実行ポリシー
型要件
-
InputIt は LegacyInputIterator の要件を満たさなければなりません。
-
ForwardIt は LegacyForwardIterator の要件を満たさなければなりません。
-
ForwardIt1 は LegacyForwardIterator の要件を満たさなければなりません。
-
ForwardIt2 は LegacyForwardIterator の要件を満たさなければなりません。
-
BinaryPred は BinaryPredicate の要件を満たさなければなりません。

戻り値

ソース範囲内で、ターゲット範囲のいずれかの要素と一致する最初の要素を指すイテレータ。

ターゲット範囲が空であるか、そのような要素が見つからない場合、last1 が返されます。

計算量

\N1 を std::distance(first1, last1)、N2 を std::distance(first2, last2) とすると:

1) 最大 N1⋅N2 回の operator== による比較。
2) 最大 N1⋅N2 回の p の適用。
3) 𝓞(N1⋅N2) 回の operator== による比較。
4) 𝓞(N1⋅N2) 回の p の適用。

例外

3,4) 実行中:
  • 並列化に必要な一時メモリリソースが利用できない場合、std::bad_alloc がスローされます。
  • アルゴリズムの引数を介してオブジェクトにアクセスしている間にキャッチされない例外がスローされた場合、動作は実行ポリシーによって決まります(標準ポリシーの場合、std::terminate が呼び出されます)。

実装例

find_first_of (1)
template<class InputIt, class ForwardIt>
InputIt find_first_of(InputIt first1, InputIt last1,
                      ForwardIt first2, ForwardIt last2)
{
    for (; first1 != last1; ++first1)
        for (ForwardIt it = first2; it != last2; ++it)
            if (*first1 == *it)
                return first1;
    return last1;
}
find_first_of (2)
template<class InputIt, class ForwardIt, class BinaryPred>
InputIt find_first_of(InputIt first1, InputIt last1,
                      ForwardIt first2, ForwardIt last2,
                      BinaryPred p)
{
    for (; first1 != last1; ++first1)
        for (ForwardIt it = first2; it != last2; ++it)
            if (p(*first1, *it))
                return first1;
    return last1;
}

例

以下のコードは、整数のベクタ内で指定された整数のいずれかを検索します。

#include <algorithm>
#include <iostream>
#include <vector>

auto print_sequence = [](const auto id, const auto& seq, int pos = -1)
{
    std::cout << id << "{ ";
    for (int i{}; const auto& e : seq)
    {
        const bool mark{i == pos};
        std::cout << (i++ ? ", " : "");
        std::cout << (mark ? "[ " : "") << e << (mark ? " ]" : "");
    }
    std::cout << " }\n";
};

int main()
{
    const std::vector<int> v{0, 2, 3, 25, 5};
    const auto t1 = {19, 10, 3, 4};
    const auto t2 = {1, 6, 7, 9};
    
    auto find_any_of = [](const auto& v, const auto& t)
    {
        const auto result = std::find_first_of(v.begin(), v.end(),
                                               t.begin(), t.end());
        if (result == v.end())
        {
            std::cout << "No elements of v are equal to any element of ";
            print_sequence("t = ", t);
            print_sequence("v = ", v);
        }
        else
        {
            const auto pos = std::distance(v.begin(), result);
            std::cout << "Found a match (" << *result << ") at position " << pos;
            print_sequence(", where t = ", t);
            print_sequence("v = ", v, pos);
        }
    };
    
    find_any_of(v, t1);
    find_any_of(v, t2);
}

出力:

Found a match (3) at position 2, where t = { 19, 10, 3, 4 }
v = { 0, 2, [ 3 ], 25, 5 }
No elements of v are equal to any element of t = { 1, 6, 7, 9 }
v = { 0, 2, 3, 25, 5 }

欠陥報告

以下の動作を変更する欠陥報告は、以前に公開されたC++標準に遡及的に適用されました。

DR 適用先 公開時の動作 正しい動作
LWG 576 C++98 first1 と last1 は LegacyForwardIteratorである必要があった それらは LegacyInputIteratorであるだけでよい
LWG 1205 C++98 ターゲット範囲が空の場合、戻り値が不明瞭だった この場合は last1 を返す

関連項目

要素の集合の中からいずれかを検索する
(アルゴリズム関数オブジェクト)
特定の基準を満たす最初の要素を見つける
(関数テンプレート & アルゴリズム関数オブジェクト)