문제

이것은 boost_foreach가 루프 종료를 확인하는 방법에 대한 질문입니다.

cout << "Testing BOOST_FOREACH" << endl;
vector<int> numbers; numbers.reserve(8);
numbers.push_back(1); numbers.push_back(2); numbers.push_back(3);
cout << "capacity = " << numbers.capacity() << endl;
BOOST_FOREACH(int elem, numbers)
{
    cout << elem << endl;
    if (elem == 2) numbers.push_back(4); 
}
cout << "capacity = " << numbers.capacity() << endl;

출력을 제공합니다

Testing BOOST_FOREACH
capacity = 8
1
2
3
capacity = 8

그러나 루프를 통해 반쯤 삽입 된 숫자 4는 어떻습니까? 유형을 목록으로 변경하면 새로 삽입 된 숫자가 반복됩니다. 재 할당이 필요한 경우 벡터 푸시 _back 작동은 포인터를 무효화하지만이 예에서는 발생하지 않습니다. 그렇다고 생각하는 질문은 왜 벡터를 사용할 때 end () 반복기가 한 번만 (루프 전)에만 평가되는 것처럼 보이지만 목록을 사용할 때 더 역동적 인 평가가 있습니까?

도움이 되었습니까?

해결책

표지 아래에서 roost_foreach는 반복자를 사용하여 요소 시퀀스를 가로 지릅니다. 루프가 실행되기 전에 엔드 반복기는 로컬 변수로 캐시됩니다. 이것을 호이 스팅이라고하며 중요한 최적화입니다. 그러나 시퀀스의 최종 반복자는 안정적이라고 가정합니다. 일반적으로 반복되는 동안 요소를 추가하거나 제거하여 시퀀스를 수정하면 자신의 Petard에 자신을 들어 올릴 수 있습니다.

http://www.boost.org/doc/libs/1_40_0/doc/html/foreach/pitfalls.html

end () 반복자가 변경을 변경하는 것을 원하지 않으면 예비가 아닌 벡터에서 크기를 조정하십시오.

http://www.cplusplus.com/reference/stl/vector/resize/

그러면 푸시하고 싶지 않지만 대신 연산자 []를 사용하십시오. 그러나 한계를 벗어나도록 조심하십시오.

다른 팁

Microsoft Debug 런타임이 벡터를 반복하는 동안 주장을 제기하는 이유에 대한 의견에서 질문이 제기되었습니다. 그 이유는 그 이유입니다 insert 다르게 정의됩니다 list 그리고 vector (그 점에 유의하십시오 push_back 그냥 an입니다 insert 시퀀스의 끝에).

C ++ 표준에 따라 (ISO/IEC 14882 : 2003 23.2.4.3, 벡터 수정 자):

삽입 중] 재 할당이 발생하지 않으면 삽입 지점의 모든 반복자와 참조가 유효합니다.

(23.2.2.3, 목록 수정 자):

삽입]은 반복자 및 참조의 유효성에 영향을 미치지 않습니다.

따라서 사용하는 경우 push_back (그리고 재 할당을 유발하지 않을 것이라고 확신합니다), 컨테이너 중 하나는 반복기를 계속 사용하여 나머지 시퀀스를 반복하는 것이 좋습니다.

그러나 벡터의 경우 정의되지 않은 행동 사용하려면 end 이전에 얻은 반복자 push_back.

이것은 질문에 대한 원형 교차로 답변입니다. 질문의 의견에서 토론에 대한 직접적인 답변입니다.

Boost 's foreach는 ITERATOR == numbers.end () 일 때 종료됩니다.

그러나 Push_back을 호출하면 현재의 현재 반복자를 무효화 할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top