ste*_*anv 46 c++ coding-style c++11
在C++ 11中,所有元素都有两个循环(基于for和for_each的范围).是否有理由偏爱另一个或者是否存在更适合的情况?
for (auto& elem: container) {
// do something with elem
}
std::for_each(container.begin(), container.end(),
[](Elem& elem) {
// do something with elem
});
Run Code Online (Sandbox Code Playgroud)
我的想法是第一个更简单,类似于其他语言中基于范围的循环,而第二个也适用于不完整容器的序列,第二个更类似于其他std算法.
Pot*_*ter 33
基于范围的for读取和写入显然更简单.它专门用于此任务.
编辑:您可以在不滥用异常的情况下打破范围.(虽然std::find_if替代也std::for_each允许这样做.)
std::for_each具有讽刺意味的是,它实际上是基于范围的替代方案,允许您选择特定值begin和end值而不是整个容器.(编辑:这可以使用简单的range类提供begin和end成员,例如Boost 提供的攻击.)
for_each在使用高阶函数时也可能更优雅:它可以用作参数bind,第三个参数已经是一个仿函数.
主要是风格问题.大多数读者可能更愿意看到for ( auto &a : b ),大多数实现现在支持它.
jua*_*nza 12
std::for_each返回循环内部使用的仿函数,因此它提供了一个干净的机制来收集有关序列中元素的一些信息.基于for循环的范围只是一个循环,因此在循环外使用的任何状态都必须在该范围之外声明.在你的例子中,如果循环的目的是改变序列的每个元素,那么根本没有太大的区别.但是如果你没有使用当时的返回值,for_each你可能会更好地使用简单的循环.顺便说一句,基于范围的循环也适用于C风格的数组和std :: strings.
这是使用返回值的一个例子for_each,虽然它不是一个非常富有想象力或有用的.这只是为了说明这个想法.
#include <iostream>
#include <array>
#include <algorithm>
struct Foo {
void operator()(int i) { if (i > 4) sum += i;}
int sum{0};
};
int main() {
std::array<int, 10> a{1,2,3,4,5,6,7,8,9,10};
Foo foo = std::for_each(a.begin(), a.end(), Foo());
std::cout << "Sum " << foo.sum << "\n";
}
Run Code Online (Sandbox Code Playgroud)
小智 6
从C++17开始,std::for_each还支持执行策略。
例如,通过编写下面的代码,您可以告诉编译器该循环可以并行化:
std::vector<int> v = {1, 2, 3};
std::for_each(std::execution::par, v.begin(), v.end(), [](int &n){ ++n; });
Run Code Online (Sandbox Code Playgroud)
您不能对基于范围的for循环执行相同的操作。