STL Algorithms

알고리즘 반복자 계약

표준 알고리즘은 컨테이너 종류보다 iterator 범위를 본다. 정렬, 탐색, 변환이 요구하는 비교 규칙과 부작용 범위를 맞춰야 결과를 믿을 수 있다.

01

범위를 자른다

begin/end, subrange, iterator 쌍으로 알고리즘이 볼 데이터를 명확히 제한한다.

02

조건을 고립한다

lambda나 함수 객체가 외부 상태를 바꾸지 않게 하여 반복 순서 의존성을 줄인다.

03

결과 위치 결정

remove 계열처럼 논리 끝을 반환하는 알고리즘과 erase를 조합해야 하는 경우를 구분한다.

find
선형 탐색 조건을 만족하는 첫 위치를 반환하고 없으면 last를 반환한다.
반환 iterator를 end와 비교한다.
sort
순서 재배치 random access iterator와 일관된 비교 함수가 필요하다.
비교 함수에서 <=를 쓰면 규칙을 깨기 쉽다.
transform
값 변환 입력 범위와 출력 위치의 크기, 겹침 규칙을 확인한다.
back_inserter가 안전한 선택일 때가 많다.
remove
지우지 않고 밀기 원소를 실제 삭제하지 않고 새 논리 끝 iterator를 반환한다.
erase-remove idiom으로 마무리한다.

반환값 · 비교 함수 · 부작용 점검

반환값 알고리즘이 bool을 주는지 iterator를 주는지, 논리 끝을 주는지 확인한다.
비교 함수 sort comparator가 비대칭성과 추이성을 만족하는가.
부작용 predicate가 외부 카운터나 컨테이너를 바꿔 순서 의존 버그를 만들지 않는가.

erase-remove

auto newEnd = std::remove_if(users.begin(), users.end(), [](const User& user) {
    return user.inactive();
        overflow-wrap: break-word;
        word-break: keep-all;
      });
users.erase(newEnd, users.end());