These questions让我很好奇每个宏的Boost和Qt的用途。
我使用过Qt,发现宏一直可以很好地满足我的需求,但从未对其性能进行过广泛的测试。我以前没有使用过Boost的产品。
我想知道什么时候是在std::for_each
上使用Qt和Boost提供的替代方法的好时机?
注意:措辞已从the original更改为使问题更客观。
最佳答案
std::for_each
的目的和功能与BOOST_FOREACH
和Q_FOREACH
宏的目的和功能有很大不同。std::for_each
首先是函数调用。这是一种算法。您称之为提供一对迭代器。在迭代器范围的每个成员上,它将使用从相关迭代器获取的值调用给定函数。
从概念上讲,std::for_each
的目的实际上是与已经存在的更具体的算法匹配。使用count
,copy
等算法,使每个元素简单地执行任意代码是有意义的。BOOST_FOREACH
和Q_FOREACH
是等效的结构(我将其统称为FOREACH
),但其行为与std::for_each
不同。FOREACH
首先是for循环。现在,听起来可能没什么不同,但请考虑一下。您不能从continue
内调用break
和std::for_each
。使用continue
可以很容易地模拟return
(尽管这也意味着您无法从发出std::for_each
调用的函数中返回)。但是,如果要停止,则无法逃脱std::for_each
循环。同样,您不能将goto
移出for_each
循环。无论哪种情况,您都可以做的最好的事情就是抛出一个异常,并且将异常用于流控制(即:不是一个好主意)。
使用std::for_each
时,必须提供一些可调用的函数。这可以是函数指针或函数对象。因此,您的代码有些地方化了。如果您在每次迭代中所做的是一个复杂的多行函数,则很好。但是,如果每个迭代的逻辑都非常简单,那么代码的可读性就会降低。FOREACH
执行本地代码块。所以代码就在那里;您无需跟踪功能即可查看每次迭代中发生的情况。
同样,调用一个函数意味着必须编写该函数。如果需要跟踪状态,则现在需要函子,该函子需要编写更多代码。
C++ 11通过lambda函数使std::for_each
更具吸引力。这消除了代码局部性问题:源代码就在那。而且由于lambda可以捕获东西,所以它几乎可以像常规for
循环一样工作。好吧,除了没有break
功能,但这通常是可以避免的。
当然,C++ 11还使它(基于FOREACH
)有效地被基于范围的for
循环淘汰了。但是,由于与C++ 11的遵循程度不同,因此在某些环境中您会使用lambda而不是基于范围的for
。
您应该使用什么取决于您。 FOREACH
很不错,如果您已经在使用Boost和/或Qt,请放心。但是我不会突然开始将这些仅用于FOREACH
。就个人而言,由于代码局部性问题,除非您也使用lambda或其他内容,否则我不会使用std::for_each
。只需使用for
循环即可。