std::find_first_of
来自 zh.cppreference.net
| 定义于头文件 <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 时,这些重载才会参与重载决议:
|
|
(直到 C++20) |
|
|
(自 C++20 起) |
参数
| first1, last1 | - | 定义源范围的迭代器对 范围 |
| first2, last2 | - | 定义目标范围的迭代器对 范围 |
| p | - | 二元谓词,若元素应被视为相等则返回 true。 谓词函数的签名应等价于以下形式:
尽管签名不需要有 |
| 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
|
参阅
(C++20) |
搜索任何一个元素 (算法函数对象) |
(C++11) |
查找满足特定条件的第一个元素 (函数模板 & 算法函数对象) |
(C++20)(C++20)(C++20) |