STL ALGORITHMS

STL iterator/predicate 계약

sort, find_if, remove_if 같은 알고리즘은 컨테이너가 아니라 iterator 구간을 받으며, iterator category와 predicate 부작용이 성능과 안정성을 결정한다.

01

구간 지정

v.begin(), v.end()는 전체 컨테이너가 아니라 시작과 끝 다음 위치를 넘긴다.

[first,last)
02

카테고리 확인

sort는 random access iterator가 필요해 list에는 list.sort를 써야 한다.

iterator category
03

조건 함수 적용

find_if/remove_if는 각 원소에 predicate를 호출해 선택 여부를 판단한다.

pure predicate 권장
04

결과 처리

remove_if는 실제 삭제가 아니라 뒤로 밀고 새 끝 iterator를 반환한다.

erase-remove idiom
sort(list)
iterator category 불일치 std::sort는 임의 접근이 필요하므로 list는 멤버 함수 sort를 사용한다.
compile error
remove_if
컨테이너 크기가 바로 줄지 않음 auto it = remove_if(...); v.erase(it, v.end())까지 해야 삭제된다.
erase-remove
invalidation
반복 중 erase로 iterator 무효화 vector erase 뒤 기존 iterator/reference가 깨질 수 있어 반환 iterator로 이어간다.
container별 규칙
predicate state
비교 함수가 strict weak ordering 위반 sort comparator가 일관되지 않으면 결과가 정의되지 않은 동작에 가까워진다.
comp(a,b)

코드 리뷰 포인트

범위 end가 포함되지 않는 반열린 구간인지, 빈 구간에서도 안전한지 본다.
복잡도 컨테이너와 iterator category가 기대 시간복잡도를 만족하는지 확인한다.
부작용 predicate가 외부 상태를 바꾸면 재호출 순서와 횟수에 의존하지 않는지 검토한다.