> 백엔드 개발 > C++ > C에서 정의된 동작을 반복하는 동안 `std::set`에서 요소를 삭제하는 것입니까, 아니면 구현에 특정한 것입니까?

C에서 정의된 동작을 반복하는 동안 `std::set`에서 요소를 삭제하는 것입니까, 아니면 구현에 특정한 것입니까?

Mary-Kate Olsen
풀어 주다: 2024-12-04 08:30:14
원래의
629명이 탐색했습니다.

Is Deleting Elements from a `std::set` During Iteration Defined Behavior in C   or Implementation-Specific?

반복 중 std::set에서 요소 삭제: 구현 의미

요소를 제거하는 동안 세트를 반복하는 것은 작업이 어려울 수 있으므로 문제가 발생할 수 있습니다. 잠재적으로 반복자를 무효화할 수 있습니다. 이러한 맥락에서 다음과 같은 질문이 생깁니다. 이 동작은 C 표준에 의해 정의됩니까, 아니면 구현에 특정합니까?

구현 종속성

C 표준에 따르면(23.1 .2.8), 세트에 요소를 삽입해도 컨테이너에 대한 반복자나 참조에 영향을 주어서는 안 되며, 요소를 지우면 반복자와 참조만 무효화되어야 합니다. 삭제된 요소에. 그러나 삭제 작업 중 반복자의 동작은 명시적으로 지정되지 않으므로 구현별 결정이 가능합니다.

GCC 구현

제공된 예제 코드에서 다음을 사용합니다. Ubuntu 10.04의 GCC 4.3.3에서는 반복 중에 세트에서 요소를 지워도 반복기가 무효화되지 않았습니다. 이는 GCC의 구현이 삭제 후에도 반복자를 계속 사용할 수 있도록 보다 완화된 접근 방식을 따른다는 것을 의미합니다.

적합성 솔루션

표준 준수를 보장하기 위해 다른 접근 방식 필요합니다. 한 가지 일반적인 해결책은 요소를 지우기 전에 반복자의 복사본을 만드는 것입니다.

for (auto it = numbers.begin(); it != numbers.end(); ) {
    if (*it % 2 == 0) {
        numbers.erase(it++);
    }
    else {
        ++it;
    }
}
로그인 후 복사

이 경우 후위 증분(it)은 이전 위치를 erasure() 함수에 전달하는 동시에 다음 요소. 접두사 증가로 인해 발생할 수 있는 잠재적인 이중 증가 문제를 방지하므로(조건이 거짓인 경우) 후위 증가가 선호됩니다.

C 11 업데이트

C 11의 출현으로 더욱 우아한 솔루션이 가능해졌습니다. 이제 erasure() 함수는 제거된 마지막 요소 뒤에 오는 요소에 대한 반복자를 반환합니다(또는 마지막 요소가 삭제된 경우 set::end). 이를 통해 더욱 간결하게 구현할 수 있습니다.

for (auto it = numbers.begin(); it != numbers.end(); ) {
    if (*it % 2 == 0) {
        it = numbers.erase(it);
    }
    else {
        ++it;
    }
}
로그인 후 복사

위 내용은 C에서 정의된 동작을 반복하는 동안 `std::set`에서 요소를 삭제하는 것입니까, 아니면 구현에 특정한 것입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿