역 반복자를 사용하여 지우기를 호출하는 방법 m_CursorStack.erase( i

나는 이런 식으로하려고합니다.

for ( std::list< Cursor::Enum >::reverse_iterator i = m_CursorStack.rbegin(); i != m_CursorStack.rend(); ++i )
{
    if ( *i == pCursor )
    {
        m_CursorStack.erase( i );
        break;
    }
}

그러나 지우기는 역 반복기가 아닌 반복기를 사용합니다. 역 이터레이터를 일반 이터레이터로 변환하는 방법이나 목록에서이 요소를 제거하는 다른 방법이 있습니까?



답변

더 많은 연구와 테스트를 거쳐 솔루션을 찾았습니다. 분명히 표준 [24.4.1 / 1]에 따르면 i.base ()와 i의 관계는 다음과 같습니다.

&*(reverse_iterator(i)) == &*(i - 1)

( 닥스 돕스 기사에서 ) :

따라서 base ()를 가져올 때 오프셋을 적용해야합니다. 따라서 해결책은 다음과 같습니다.

m_CursorStack.erase( --(i.base()) );

편집하다

C ++ 11 업데이트

reverse_iterator i는 변경되지 않았습니다.

m_CursorStack.erase( std::next(i).base() );

reverse_iterator i가 고급입니다.

std::advance(i, 1);
m_CursorStack.erase( i.base() );

이전 솔루션보다 훨씬 명확합니다. 필요한 것을 사용하십시오.


답변

참고 m_CursorStack.erase( (++i).base())A의 사용하는 경우 문제가 될 수 for는 i 값을 변경하기 때문에 (원래의 질문 참조) 루프를. 올바른 표현은m_CursorStack.erase((i+1).base())


답변

… 또는이 요소를 목록에서 제거하는 다른 방법은 무엇입니까?

-std=c++11플래그에는 (for auto) 이 필요합니다 .

auto it=vt.end();
while (it>vt.begin())
{
    it--;
    if (*it == pCursor) //{ delete *it;
        it = vt.erase(it); //}
}

답변

이 페이지에 아직 올바른 해결책이 없다는 것이 유감입니다. 따라서 다음은 올바른 것입니다.

순방향 반복자의 경우 솔루션은 간단합니다.

std::list< int >::iterator i = myList.begin();
while ( ; i != myList.end(); ) {
  if ( *i == to_delete ) {
    i = myList.erase( i );
  } else {
    ++i;
  }
}

역 이터레이터의 경우 동일한 작업을 수행해야합니다.

std::list< int >::reverse_iterator i = myList.rbegin();
while ( ; i != myList.rend(); ) {
  if ( *i == to_delete ) {
    i = decltype(i)(myList.erase( std::next(i).base() ));
  } else {
    ++i;
  }
}

노트:

  • 당신은을 구성 할 수 reverse_iterator반복자에서
  • 의 반환 값을 사용할 수 있습니다 std::list::erase

답변

reverse_iteratorbase()방법을 사용하고 결과를 줄이는 것이 여기에서 효과가 있지만 reverse_iterators에 일반 iterators 와 동일한 상태가 부여되지 않았다는 점은 주목할 가치가 있습니다. 일반적으로 이와 같은 이유로 일반 iterators reverse_iterator에서 const_iterators 및 const_reverse_iterators 및 s 를 선호해야합니다 . 이유에 대한 자세한 내용은 Dr Dobbs Journal 을 참조하십시오 .


답변

typedef std::map<size_t, some_class*> TMap;
TMap Map;
.......

for( TMap::const_reverse_iterator It = Map.rbegin(), end = Map.rend(); It != end; It++ )
{
    TMap::const_iterator Obsolete = It.base();   // conversion into const_iterator
    It++;
    Map.erase( Obsolete );
    It--;
}

답변

그리고 여기에 삭제의 결과를 역 반복자로 다시 변환하여 컨테이너에서 요소를 지우고 반대로 반복하는 코드가 있습니다. 조금 이상하지만 첫 번째 또는 마지막 요소를 지우는 경우에도 작동합니다.

std::set<int> set{1,2,3,4,5};

for (auto itr = set.rbegin(); itr != set.rend(); )
{
    if (*itr == 3)
    {
        auto it = set.erase(--itr.base());
        itr = std::reverse_iterator(it);
    }
    else
        ++itr;
}