Namespaces
Variants

std::find_first_of

来自 zh.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) (自 C++20 起为 constexpr)
template< class InputIt, class ForwardIt, class BinaryPred >
InputIt find_first_of( InputIt first1, InputIt last1,
                       ForwardIt first2, ForwardIt last2,
                       BinaryPred p );
(2) (自 C++20 起为 constexpr)
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)s 它们只需要是 遗留输入迭代器 (LegacyInputIterator)s
LWG 1205 C++98 如果目标范围为空,返回值不明确 在这种情况下返回 last1

参阅

搜索任何一个元素
(算法函数对象)
查找满足特定条件的第一个元素
(函数模板 & 算法函数对象)