我知道历史上使用标准算法,如for_each
而不是for
循环更易读。但我认为在c++11中,普通的for循环比众多标准算法及其对应的回调函数更简洁。
我这样想错了吗?许多标准算法已经过时了吗?这些方法提供了哪些不同的好处?
请根据自己的判断力使用合适的方法。
C++11引入了lambda表达式和更好的bind表达式,使得许多算法在C++中的使用变得更加简单明了,你可以相对简洁地指定函数对象。但是,基于范围的for
循环也是一个完全合法的选择。
如果你只需要在循环体中执行一两个语句,那么尽管使用基于范围的循环。如果你需要在一组对象上调用成员函数,则可以考虑使用for_each
和mem_fn
。如果绑定表达式看起来足够清晰,则可以使用它。但无论你做什么,如果发现自己将过多的逻辑集中到一个地方,请考虑重构代码,并为较小的工作组件命名以提高可读性。
C++提供了许多工具,一个工具的存在并不意味着另一个工具无用。像C++这样的强大编程语言面向有经验的用户,经验会帮助你选择正确的工具来完成正确的工作。
就可读性而言,使用基于范围的for循环现在可能比使用std::for_each
稍微好一些。但这并不意味着for_each
已经过时。
请看下面的代码:
auto myVals = getManyValsInAContainer();
for (auto& val : myVals)
{
doStuff(val);
}
它做的事情与这段难以阅读的代码相同:
auto myVals = getManyValsInAContainer();
for (auto it = myVals.begin(), end = myVals.end(); it != end; ++it)
{
doStuff(*it);
}
std::deque
,这意味着您的值在大块连续的内存中,有一些指针来跟踪这些块的位置。对于知道实现方式的人来说,遍历该容器的所有元素很容易:只需要双重循环即可遍历每个块中的每个元素。operator++()
从一个元素移动到下一个元素。每次这样做时,operator++()
必须检查下一个元素是否在同一个块中,或者是否需要转到下一个块。这些调用是完全独立的,因此没有办法使事情更有效率。std::for_each
时是否有任何不同呢?首先,它是一个函数模板,因此它可以专门化。它也是STL的一部分,这意味着实现它的人员非常了解std::deque
(或者您正在使用的其他STL容器)的实现方式,并且他们可以使std::for_each
成为容器类的友元(或者做任何其他需要做的事情),以便高效地进行操作,而不是依赖于多个对operator++()
的调用。std::for_each
并不过时。可读性只是它的一项优点,但在迭代STL容器时,它仍然比任何for循环更有效率。for_each
的可读性肯定有争议)[](int a, int b){return a+b;}
与_1+_2
进行比较。 - KitsuneYMG
break
来中断一个 for 循环,但是你不能使用break
来中断一个for_each
循环,所以它们并不完全等价。我会尽可能使用for_each
。 - sbabbifor_each
,但正文谈论了一些神秘的“具有相应回调函数的众多标准算法”和“许多标准算法”?除了for_each()
之外,还有哪些特定的<algorithm>
与本文相关?如何将它们替换为范围-for
循环? - underscore_d