使用“break”时BOOST_FOREACH进入无限循环?

时间:2012-05-15 15:21:17

标签: c++ boost c++03

以下代码段在内部进入无限循环 BOOST_FOREACH声明,我无法弄清楚原因。尽我所能 从Boost文档中可以看出,使用“break”应该没问题 在BOOST_FOREACH循环内。知道这里可能出现什么问题吗?

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;
}

如果我用for循环替换BOOST_FOREACH循环(使用迭代器 从sectors.begin()sectors.end()),它运作得很好(没有 无限循环)。

版本&amp;其他信息:

  • 提升:1.40.0
  • gcc:4.1.2
  • 架构:x86_64
  • 我只对发布版本有这种行为;如果我进行调试构建,那么它会按预期工作。
  • 在visual studio下编译时,它按预期工作 - 即没有无限循环。

回应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();
}

此扩展的一个显着特征是有两个嵌套for循环。我无法弄清楚内部循环和外部循环中发生了什么,但是有可能(正如大卫建议的那样)我正在打破内部循环,并且BOOST_FOREACH不能正确处理某些内部循环原因是什么?

1 个答案:

答案 0 :(得分:4)

我打赌简化功能:

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

解决了这个问题。

虽然经过优化,但很难知道......但至少你的代码会更具可读性。我没有你的gcc版本来测试,从来没有遇到过我的(或铿锵),所以我只能建议:x