2012-05-29 2 views
13

다음은 C++ 표준에 따라 정의 된 결과를 제공합니까?목록이 비어있을 때 std :: list : begin()의 동작

std::list<int> myList; 
std::list<int>::iterator myIter = myList.begin(); // any issues? 
myList.push_back(123); 
myIter++;         // will myIter point to the 123 I pushed? 

저는 이것을 사용하는 컴파일러에서 테스트 할 수 있지만 좀 더 확실한 대답을 원합니다.

+0

내 생각에, 실제로는 이것이 좋은 질문이라고 생각합니다. 그것은 목록 일 것입니다 ... 어쩌면 이것이 작동 할 수도 있습니다 ... (물론 아닙니다) – jcoder

답변

18

모든 표준 반복자와 컨테이너 유형이 점에서 동일하게 동작 :

§23.2.1 [container.requirements.general] p6

begin() retu 컨테이너 내의 최초의 요소를 참조하는 반복자. end()은 컨테이너의 과거 - 끝 값인 반복자를 리턴합니다. 컨테이너가 비어 있으면 begin() == end();

그리고 ++it을위한 전제 조건으로, it 같은, 과거 - 더 - 끝 반복자 (즉, 당신이 end()에서 무엇을 얻을)의 경우에는 해당되지 않습니다하는 dereferenceable한다 테이블 (107) §24.2.3 [input.iterators] 요구에 당신 정의되지 않은 행동의 두려운 영역을 밟고 있습니다.

+0

그래서 만약 그것이'myIter -'였다면, 그것은 push 된 값을 가리킬 것입니까? – balki

4
std::list<int> myList; 
std::list<int> myIter = myList.begin(); 

이터레이터는 myList.end()으로 초기화하는 경우와 동일한 값을 갖습니다. 이터레이터는 지나친 끝 위치로 초기화됩니다. 엘리먼트를리스트에 넣은 후에도 반복자는 여전히 한 끝을 가리킨다. 증분하면 정의되지 않은 동작이 호출됩니다.

UPDATE :

예를 당신이 -D_GLIBCXX_DEBUG와 GCC와 조각을 컴파일하는 경우, 결과 실행이 중단됩니다

/usr/include/c++/4.6/debug/safe_iterator.h:236:error: attempt to increment 
    a past-the-end iterator. 

Objects involved in the operation: 
iterator "this" @ 0x0x7fffc9548fb0 { 
type = N11__gnu_debug14_Safe_iteratorINSt9__cxx199814_List_iteratorIiEENSt7__debug4listIiSaIiEEEEE (mutable iterator); 
    state = past-the-end; 
    references sequence with type `NSt7__debug4listIiSaIiEEE' @ 0x0x7fffc9548fb0 
} 
zsh: abort (core dumped) ./listiter 
+0

... 원형 목록을 가지고있을 때 하나의 과거 - 끝은 당신에게 합법적 인 시작점을 줄 수도 있다는 것을 제외하고는 정의. 그럼 당신은 절대적으로 확신합니까 ... 아니면 교양있는 추측을합니까? – omatai

+5

@omatai :'std :: list <>'는 원형이 아닙니다. – wilx

+0

아, 예, 피곤한 마음에서 저는 이중 연결 목록을 만들 때마다 항상 "머리말"을 완성한 머리/꼬리가 하나 있었기 때문에 "이중 연결"과 "원형"을 혼동했습니다. 원". D' Oh! 나는 집에 갈 필요가있다. – omatai

관련 문제