2009-11-05 1 views
3

Scott Meyers "Effective STL”에서 erase-remove idiom (항목 32)을 읽었을 때이 질문을 받았습니다.지우기 지우기 관용구 : 지우기 전에 지우개를 제거하면 어떻게됩니까?

vector<int> v; 
... 
v.erase(remove(v.begin(), v.end(), 99), v.end()); 

remove은 기본적으로 범위의 "새 논리 끝"에서 시작하고 범위의 실제 끝에서 삭제하는 요소가 될 때까지 계속 "새 논리 끝"원래 범위의 요소를 반환 . 용기

좋은 소리 이제 내 질문 물어 보자 :.. 위의 예에서

, removev.end() 99 경우가 vector v에없는 반환 할 수 있습니다 기본적으로 방법을 지울 past-the-end-iterator을 통과

0123.
  1. past-the-end-iteratorerase 방법으로 전달되면 어떻게됩니까? 표준이 그것을 UB라고합니까? 이것에 대한 어떤 아이디어

vector<int> v; 
    ... 
    vector<int>::iterator newEndIter = remove(v.begin(), v.end(), 99); 
    if(newEndIter != v.end()) 
    { 
    v.erase(newEndIter, v.end(); 
    } 

: 그것은 정의되지 않은 동작 인 경우

  • , 스콧 마이어의 책에서 다음 erase-remove idiom 예처럼 보였다해야?

  • +0

    정의에 따르면 v.end()는 'past-the-end'가 아니며 끝입니다. x –

    +4

    @Matthieu M. std :: vector :: end()의 설명서는 다음과 같이 설명합니다. "반복기를 반환합니다. 벡터 컨테이너의 past-the-end 요소를 참조하십시오. " –

    +0

    @ Julien-L : 그건 나쁜 표현입니다. 마지막 반복자는 한 요소를 지나치는 요소입니다. C++ 사양이 실제로 그렇게 말하고 있습니까? 그것은 놀랄 것입니다. –

    답변

    10

    나는 v.erase(v.end(), v.end())이 잘 정의되어 있고 아무 것도 지우지 않을 것이라고 생각합니다.

    +1

    유효한 반복자는 [v.begin(), v.end()] INCLUSIVE에 있습니다. –

    10

    C++ 표준은 erase(q1,q2) 구성원이 "[q1, q2] 범위의 요소를 지 웁니다"(23.1.1 절 참조)라고 말합니다. 범위에서 마지막 요소를 제외하므로

    v.erase(v.end(), v.end()); 
    

    이 유효하고 아무 것도 지우지 않습니다. 빈 범위를 삭제하는 것은 어떤 조합입니다 :

    +0

    수학 표기법 [x, y]의 의미를 설명해야 할 수 있습니다. 수학 (또는 관련 과목)에 학위가없는 한 당신은 아마 모른다. –

    +2

    정말요? 나는 수학에 학위가 있지만 솔직히 항상이 표기법이 잘 알려져 있다고 생각했습니다. – rlbond

    +1

    Wikipedia 페이지는 http://en.wikipedia.org/wiki/Interval_%28mathematics%29에서 수학 간격으로 찾을 수 있습니다. –

    2

    C++ Reference 주장 : first==last이 경우

    반복자 first는 dereferenceable 할 필요가 없습니다.