我喜欢for_each()
语法,但是当条件满足时从一个语言中逃脱是不可能的(我可以抛出异常,但这似乎有点矫枉过正)。
我已经使用find_if()
来做这件事,但我有一位经理觉得以这种方式使用它有点模糊。
我正在使用MSVS2010,因此无法使用for(:)
。
我唯一的选择是for(auto i = container.begin(); i != container.end(); ++i)
吗?
答案 0 :(得分:2)
我建议使用BOOST_FOREACH
,这只是一个标题BTW,所以你甚至不需要构建和链接到提升。
#include <string>
#include <iostream>
#include <boost/foreach.hpp>
int main()
{
std::string hello( "Hello, world!" );
BOOST_FOREACH( char ch, hello )
{
std::cout << ch;
if(ch == 'o')break;
}
return 0;
}
如果不能选择提升,只需使用正常的for循环,就像你说的那样
for(auto i = container.begin(); i != container.end(); ++i)
这不是什么大不了:),或者你可以升级你的编译器。如果没有看到手头的问题和您的代码,我们无法判断find_if
是否模糊不清。
这是我的for_each版本,不要相信它100%提升的时间很长而且我确信我的有很小的差异,因为它太短了(也有一个名字泄漏到你的空间,IDT提升了)< strong>这是我第三次这样做,非常确定除了泄漏的变量名obscure_variable_name
之外它是完全正确的。
#include <string>
#include <iostream>
#include <iterator>
#define AARON_FOREACH(var,container) \
if(int obscure_variable_name = 0) {} else \
for(auto var = *std::begin(container);obscure_variable_name+1;obscure_variable_name=-1) \
for(auto iter = std::begin(container); \
iter != std::end(container)?( var = *iter), true : false ; ++iter)
int main()
{
std::string hello( "Hello, world!" );
AARON_FOREACH(ch,hello)
{
std::cout << ch;
}
std::cout<<std::endl;
AARON_FOREACH(ch,hello)
{
std::cout << ch;
if(ch == 'o')break;
}
return 0;
}
答案 1 :(得分:2)
使用std::find_if
是更好的方法。正如Scott Meyers在他的 Effective STL 一书中所说:
指南:首选算法调用显式循环。算法调用通常更清晰并降低复杂性。如果没有合适的算法,为什么不写呢?你会再次使用它。
将std::find_if
与std::for_each
一起使用会更加清晰,因为它会分离逻辑以选择要处理的项目以及处理项目的逻辑。这也有助于提高可测试性。
此外,std::find_if
和std::for_each
可以组合在一起以创建新的算法,例如for_each_until
,如下所示:
template <class Iterator, class F, class Cond>
void for_each_until(Iterator b, Iterator e, F f, Cond cond)
{
auto stop = std::find_if(b, e, cond);
std::for_each(b, stop, f);
}
您可以再次使用。
答案 2 :(得分:1)
我认为我首先要为此通用编写一个小算法:
template <class Iter, class F, class Cond>
void for_each_until(Iter b, Iter e, F f, Cond cond) {
for( ; b != e; ++b) {
if (cond(*b))
return;
f(*b);
}
}
有了这个,任务变得相当微不足道。例如,要执行f
集合int
中的所有c
s,打破/如果我们得到负数,我们将使用类似这样的代码:
for_each_until(c.begin(), c.end(), f, [](int i) { return i < 0; } );
答案 3 :(得分:0)
而不是std::for_each
,如何使用基于范围的for循环?
for (const auto& item : container)
{
if (!condition_met) { continue; }
// process item
}
答案 4 :(得分:0)
创建一个跟踪是否达到中断条件的仿函数,如果是,则立即返回。
#include <algorithm>
#include <vector>
#include <iostream>
struct addOneUntilFive {
void operator() (int& i) {
if (breakReached)
return;
if (i == 5) {
breakReached = true;
}
i += 1;
std::cout << i << std::endl;
}
bool breakReached;
} instance;
int main() {
std::vector<int> foo{1,2,3,4,5,6,7,8,9};
std::for_each(foo.begin(), foo.end(), instance);
}
答案 5 :(得分:0)
正如你从答案中看到的那样,没有你不能在没有std::for_each
运行的情况下突破:
std::for_each
。即。 你是对的。是的,使用适当的循环。