2012-05-15 2 views
4

다음 코드 세그먼트는 BOOST_FOREACH 문 내에 무한 루프를 입력하고 이유를 파악할 수 없습니다. 내가 할 수있는 한, 은 Boost 문서에서 말해서 BOOST_FOREACH 루프 내에서 "break" 을 사용하는 것이 좋을 것이다. 어떤 생각이 잘못되었을 지 모릅니다."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; 
} 

나는이 루프 (sectors.end()sectors.begin()에서 반복자 사용)로 BOOST_FOREACH 루프를 교체 할 경우, 다음이 잘 (더 무한 루프)를 작동하지 않습니다.

버전 & 추가 정보 :

  • 부스트 : 1.40.0
  • GCC : 4.1.2
  • 아키텍처 : x86_64의 릴리스 빌드를 위해 나는 단지이 동작을 얻을
  • ; 디버그 빌드를 수행하면 예상대로 작동합니다.
  • Visual Studio에서 컴파일하면 예상대로 작동합니다. 즉, 무한 루프가 발생하지 않습니다. 내가 gcc -E을 실행할 때 MKB의 질문에 대한 응답으로

, 여기에 내가 무엇을 얻을 :이 확장

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

하나의 주목할만한 특징은 루프에 대한 두 개의 중첩이 있다는 것입니다. 내부 루프와 외부 루프에서 무슨 일이 일어나는지 알 수는 없지만, (David이 제시 한 바와 같이) 내부 루프에서 벗어날 가능성이 있으며, 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 

문제를 해결 :

+0

대신 C++ 11 범위 for 루프를 사용하지 않는 이유는 무엇입니까? –

+0

여러 아키텍처를 포함하여 사용할 수있는 컴파일러 버전을 제한하는 외부 제약 조건이 있습니다. 불행히도 그 의미는 내가 C++ 11을 사용할 수 없다는 것을 의미한다. 나는 C++ 98을 사용하는 데 어려움을 겪고있다. –

+0

C++ 98 또는 C++ 03? 좋아, 나는 컴파일러 버전을 놓쳤다. 그것은 C++ 03 –

답변

4

나는 기능을 단순화하는 내기.

최적화가되었지만 알기가 어렵지만 최소한 코드가 읽기 쉽습니다. gcc의 버전을 테스트 할 필요가 없으며 광산 (또는 clang)과 관련하여 문제가 없었으므로 다음과 같이 제안 할 수 있습니다. x

+0

글쎄,이 코드 블록은 함수의 중간에있다. (즉, 결과를 리턴하는 것이 아니라 다른 것을한다.) 그렇게하기 위해 도우미 함수를 추가해야한다. 아마도 옳은 일이다. 하지만 내가 가진 주요 문제는이 특별한 경우가 아니라 BOOST_FOREACH가 내가 기대하는 바를 수행 할 수 있는지 여부입니다. –

+1

@EdwardLoper : 당신은'BOOST_FOREACH'를 믿을 수 있지만 컴파일러를 믿을 수 있습니까? 그것은 또 다른 질문입니다 : x –

+0

너무 똑같습니다. 그러나 보통 나는 컴파일러의 약점을 적절히 다루고 가면 부스트를 신뢰할 수 있습니다. :) –

관련 문제