std::for_each_n
来自 cppreference.cn
定义于头文件 <algorithm> |
||
template< class InputIt, class Size, class UnaryFunc > InputIt for_each_n( InputIt first, Size n, UnaryFunc f ); |
(1) | (自 C++17 起) (constexpr 自 C++20 起) |
template< class ExecutionPolicy, class ForwardIt, class Size, class UnaryFunc > |
(2) | (自 C++17 起) |
将给定的函数对象 f 应用于范围 [
first,
first + n)
中每个迭代器解引用的结果。如果 f 返回结果,则忽略该结果。
1) f 从 first 开始按顺序应用。
如果
UnaryFunc
不是 可移动构造 (MoveConstructible),则行为未定义。2) f 可能不按顺序应用。算法根据 policy 执行。
仅当满足以下所有条件时,此重载才参与重载解析
std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> 为 true。 |
(C++20 之前) |
std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>> 为 true。 |
(自 C++20 起) |
如果
UnaryFunc
不是 可复制构造 (CopyConstructible),则行为未定义。如果 n >= 0 不为 true,则行为未定义。
如果迭代器类型 (InputIt
/ForwardIt
) 是可变的,则 f 可以通过解引用的迭代器修改范围的元素。
与其余并行算法不同,即使序列中的元素是 可平凡复制 (TriviallyCopyable),for_each_n
也不允许复制它们。
目录 |
[编辑] 参数
first | - | 要应用函数的范围的开始 |
n | - | 要应用函数的元素数量 |
policy | - | 要使用的执行策略 |
f | - | 函数对象,应用于范围 [ first, first + n) 中每个迭代器解引用的结果函数的签名应等效于以下内容 void fun(const Type &a); 签名不需要具有 const &。 |
类型要求 | ||
-InputIt 必须满足 旧式输入迭代器 (LegacyInputIterator) 的要求。 | ||
-ForwardIt 必须满足 旧式前向迭代器 (LegacyForwardIterator) 的要求。 | ||
-Size 必须可转换为整型类型。 |
[编辑] 返回值
等于 first + n 的迭代器,或更正式地说,等于 std::advance(first, n)。
[编辑] 复杂度
正好 n 次 f 的应用。
[编辑] 异常
具有名为 ExecutionPolicy
的模板参数的重载按如下方式报告错误
- 如果作为算法一部分调用的函数的执行抛出异常,并且
ExecutionPolicy
是标准策略之一,则调用 std::terminate。对于任何其他ExecutionPolicy
,行为是实现定义的。 - 如果算法无法分配内存,则抛出 std::bad_alloc。
[编辑] 可能的实现
另请参见 libstdc++、libc++ 和 MSVC stdlib 中的实现。
template<class InputIt, class Size, class UnaryFunc> InputIt for_each_n(InputIt first, Size n, UnaryFunc f) { for (Size i = 0; i < n; ++first, (void) ++i) f(*first); return first; } |
[编辑] 示例
运行此代码
#include <algorithm> #include <iostream> #include <vector> void println(auto const& v) { for (auto count{v.size()}; const auto& e : v) std::cout << e << (--count ? ", " : "\n"); } int main() { std::vector<int> vi{1, 2, 3, 4, 5}; println(vi); std::for_each_n(vi.begin(), 3, [](auto& n) { n *= 2; }); println(vi); }
输出
1, 2, 3, 4, 5 2, 4, 6, 4, 5
[编辑] 参见
将函数应用于元素范围,并将结果存储在目标范围中 (函数模板) | |
范围 for 循环(C++11) |
在范围内执行循环 |
将一元函数对象应用于范围中的元素 (函数模板) | |
(C++20) |
将函数对象应用于序列的前 N 个元素 (算法函数对象) |