2009-06-09 5 views
4

목록을 반복하는 BOOST_FOREACH 루프가 있습니다. 아쉽게도 특정 항목에 반복자를 캐시해야합니다. BOOST_FOREACH 루프의 반복자에 액세스

typedef List::iterator savedIterator; 

BOOST_FOREACH(Item &item, list) 
{ 
// stuff... 
    if (condition) 
    savedIterator = &item; // this won't work 

// do more stuff...  
} 

는 분명 내가 루프에 대한 list.begin을() .. list.end()를 사용하여이 작업을 수행 할 수 있습니다,하지만 난 BOOST_FOREACH를 좋아하는 성장했습니다. 이 둘 사이에 방법이 있을까요?

답변

7

루프 내부의 현재 항목을 가리키는 반복기에 액세스 할 수 없기 때문에 불가능합니다.

현재 항목 데이터를 사용하여 목록에서 반복기를 가져올 수 있지만 성능상의 이유는이 항목을 따르는 것이 좋습니다.

당신이 이미 제안한 솔루션을 list.begin() .. list.end()와 함께 사용하는 것이 좋습니다. 제 의견으로는 구현하기 쉽고 인식하기 쉽습니다.

4

Boost.Foreach를 사용하면 역 참조 된 반복기에 대한 참조로 인해 Boost.Foreach가 설계 한 것이므로 범위 내 요소에 대한 액세스를 단순화 할 수 있습니다. 당신은 단지 기준에 맞는 단일 요소를 찾고 있다면 그러나, 당신은 std::find_if()을 시도 할 수 있습니다 :

struct criteria { 
    template <class T> 
    bool operator()(T const & element) const { 
    return (element /* apply criteria... */)? true : false; 
    } 
}; 

// somewhere else 
List::iterator savedIterator = 
    std::find_if(list.begin(), list.end(), criteria()); 

당신이 전체 목록에 대한 작업을 적용 할 것 또한 보이는 - 어떤 경우에는 내가 ' boost::transform_iterator과 같은 Boost.Iterators와 함께 std::min_element() 또는 std::max_element()과 같은 것을 사용하는 것이 좋습니다. 사람들이 이렇게하지 않는 이유

struct transformation { 
    typedef int result_type; 
    template <class T> 
    int operator()(T const & element) const { 
    // stuff 
    int result = 1; 
    if (condition) result = 0; 
    // more stuff 
    return result; 
    } 
}; 

// somewhere else 
List::iterator savedIterator = 
    std::min_element(
    boost::make_transform_iterator(list.begin(), transformation()), 
    boost::make_transform_iterator(list.end(), transformation()), 
).base(); 
+2

Upvoted을,하지만 때문에 내가 시간에 C++를 얼마나 싫어하는지 생각 나게한다. – Roddy

1

는 내가 가지 궁금 :

#define foreach(iter_type, iter, collection) \ 
for (iter_type iter = collection.begin(); iter != collection.end(); ++iter) 
+1

'collection'이 부작용이있는 표현식이라면? 매크로는 두 번 평가할 것입니다. 또한 전통적인 'foreach'의 요점은 반복자 (그리고 길고 다루기 힘든 유형 이름)를 전혀 사용하지 않고 직접 값을 얻는 것입니다. –

+0

collection이 표현식이면 좋은 점입니다. 이 경우 표현식을 평가 한 다음이를 참조로 foreach에 전달하십시오. collection_type & c = foreach (iter_type, it, c) ... 반복기에 대한 액세스 권한은 유연성 (예 :이 게시물의 질문)에 유용합니다. 나는 그것이 지불 할 가격이 너무 많다고 생각하지 않는다. 하지만 어쩌면 그게 내 특별한 스타일 일 것입니다 ... –

+0

'BOOST_FOREACH'는 당신이 생각하는 것처럼 단순하지 않습니다. 그 기사를 읽어주세요 예를 들어'collection'은 반복자가없는 배열일까요? http://cplusplus.bordoon.com/boost_foreach_techniques.html http://www.artima.com/cppsource/foreach.html (BOOST_FOREACH의 작성자는이 기사를 작성했습니다) –