以下代码段在BOOST_FOREACH语句内部进入了无限循环
,我不知道为什么。据我从Boost文档中得知,在BOOST_FOREACH循环中使用“ break”应该没问题。知道这里可能出什么问题吗?
std::vector<std::wstring> sectors = getSectors();
if (!_sectorCodes.empty()) { // _sectorCodes is a std::set<std::wstring>.
bool ok = false; // did we find the sector code we wanted?
BOOST_FOREACH(Symbol sector, sectors) {
if (_sectorCodes.find(sector) != _sectorCodes.end()) {
ok = true;
break;
}
}
if (!ok) return NULL;
}
Run Code Online (Sandbox Code Playgroud)
如果我将BOOST_FOREACH循环替换为for循环(使用从sectors.begin()to 的迭代器sectors.end()),那么它就可以正常工作(没有无限循环)。
版本和其他信息:
回答mkb的问题,这是我运行时得到的结果gcc -E:
if (!_sectorCodes.empty()) {
bool ok = false;
if (boost::foreach_detail_::auto_any_t _foreach_col148 = boost::foreach_detail_::contain( (sectors) , (true ? 0 : boost::foreach_detail_::or_( boost::foreach_detail_::and_( boost::foreach_detail_::not_(boost::foreach_detail_::is_array_(sectors)) , (true ? 0 : boost::foreach_detail_::is_rvalue_( (true ? boost::foreach_detail_::make_probe(sectors) : (sectors)), 0))) , boost::foreach_detail_::and_( boost::foreach_detail_::not_(boost_foreach_is_noncopyable( boost::foreach_detail_::to_ptr(sectors) , boost_foreach_argument_dependent_lookup_hack_value)) , boost_foreach_is_lightweight_proxy( boost::foreach_detail_::to_ptr(sectors) , boost_foreach_argument_dependent_lookup_hack_value)))))) {} else if (boost::foreach_detail_::auto_any_t _foreach_cur148 = boost::foreach_detail_::begin( _foreach_col148 , (true ? 0 : boost::foreach_detail_::encode_type(sectors, boost::foreach_detail_::is_const_(sectors))) , (true ? 0 : boost::foreach_detail_::or_( boost::foreach_detail_::and_( boost::foreach_detail_::not_(boost::foreach_detail_::is_array_(sectors)) , (true ? 0 : boost::foreach_detail_::is_rvalue_( (true ? boost::foreach_detail_::make_probe(sectors) : (sectors)), 0))) , boost::foreach_detail_::and_( boost::foreach_detail_::not_(boost_foreach_is_noncopyable( boost::foreach_detail_::to_ptr(sectors) , boost_foreach_argument_dependent_lookup_hack_value)) , boost_foreach_is_lightweight_proxy( boost::foreach_detail_::to_ptr(sectors) , boost_foreach_argument_dependent_lookup_hack_value)))))) {} else if (boost::foreach_detail_::auto_any_t _foreach_end148 = boost::foreach_detail_::end( _foreach_col148 , (true ? 0 : boost::foreach_detail_::encode_type(sectors, boost::foreach_detail_::is_const_(sectors))) , (true ? 0 : boost::foreach_detail_::or_( boost::foreach_detail_::and_( boost::foreach_detail_::not_(boost::foreach_detail_::is_array_(sectors)) , (true ? 0 : boost::foreach_detail_::is_rvalue_( (true ? boost::foreach_detail_::make_probe(sectors) : (sectors)), 0))) , boost::foreach_detail_::and_( boost::foreach_detail_::not_(boost_foreach_is_noncopyable( boost::foreach_detail_::to_ptr(sectors) , boost_foreach_argument_dependent_lookup_hack_value)) , boost_foreach_is_lightweight_proxy( boost::foreach_detail_::to_ptr(sectors) , boost_foreach_argument_dependent_lookup_hack_value)))))) {} else for (bool _foreach_continue148 = true; _foreach_continue148 && !boost::foreach_detail_::done( _foreach_cur148 , _foreach_end148 , (true ? 0 : boost::foreach_detail_::encode_type(sectors, boost::foreach_detail_::is_const_(sectors)))); _foreach_continue148 ? boost::foreach_detail_::next( _foreach_cur148 , (true ? 0 : boost::foreach_detail_::encode_type(sectors, boost::foreach_detail_::is_const_(sectors)))) : (void)0) if (boost::foreach_detail_::set_false(_foreach_continue148)) {} else for (Symbol sector = boost::foreach_detail_::deref( _foreach_cur148 , (true ? 0 : boost::foreach_detail_::encode_type(sectors, boost::foreach_detail_::is_const_(sectors)))); !_foreach_continue148; _foreach_continue148 = true) {
if (_sectorCodes.find(sector) != _sectorCodes.end()) {
ok = true;
break;
}
}
if (!ok) return PatternFeatureSet_ptr();
}
Run Code Online (Sandbox Code Playgroud)
此扩展的一个显着特征是有两个嵌套的for循环。我无法弄清楚内部和外部循环中发生了什么,但有可能(正如大卫建议的那样)我打破了内部循环,而BOOST_FOREACH不能正确地处理某些内部循环原因?
我敢打赌简化这个功能:
std::wstring const* find(std::vector<Symbol> const& sectors) {
if (!_sectorCodes.empty()) {
BOOST_FOREACH(Symbol sector, sectors) {
std::set<Symbol>::const_iterator it = _sectorCodes.find(sector);
if (it != _sectorCodes.end()) { return &*it; }
}
}
return NULL;
} // find
Run Code Online (Sandbox Code Playgroud)
解决了这个问题。
虽然通过优化,很难知道......但至少你的代码会更具可读性。我没有你的 gcc 版本来测试,而且我的(或 clang)从来没有遇到过任何问题,所以我只能建议 :x