Function Objects

함수 객체 상태와 타입

람다와 functor는 함수처럼 호출되지만 객체이기도 하다. 비교자, predicate, 전략 객체에 상태를 담을 수 있어 알고리즘과 컨테이너의 행동을 바꾼다.

01

행동을 값 생성

정렬 기준이나 필터 조건을 객체로 넘기면 알고리즘은 데이터와 정책을 분리해 실행한다.

02

상태를 담는다

threshold나 설정값이 필요한 predicate는 멤버 변수로 명확히 보관한다.

03

수명을 검토한다

람다 참조 캡처가 알고리즘 호출 이후에도 저장되는지, 컨테이너 비교자로 남는지 확인한다.

functor
이름 있는 호출 객체 여러 곳에서 재사용하거나 상태 의미를 문서화해야 할 때 이름 있는 호출 객체가 기준을 남긴다.
operator() const 여부도 의미가 있다.
lambda
국소 정책 짧은 predicate나 변환 규칙을 호출부 가까이에 둔다.
캡처 목록을 좁힌다.
comparator
컨테이너 정렬 규칙 set/map에 저장되면 컨테이너 수명 동안 규칙이 유지되어야 한다.
상태 변경은 위험하다.
transparent
이종 검색 std::less<>처럼 타입 변환 없이 string_view 검색을 허용할 수 있다.
C++14 이후 관례를 확인한다.

캡처 · 비교 규칙 · 재사용 점검

캡처 [&]로 불필요한 참조까지 잡아 dangling 위험을 만들지 않는가.
비교 규칙 상태 있는 comparator가 실행 중 바뀌어 컨테이너 순서를 깨지 않는가.
재사용 람다가 길어졌다면 이름 있는 functor로 의미를 드러내는 편이 나은가.

상태 있는 predicate

struct AtLeast {
    int limit;
    bool operator()(int value) const { return value >= limit; }
};

auto count = std::count_if(scores.begin(), scores.end(), AtLeast{80});