조건 검색이란?

find의 한계

  • std::find값이 정확히 같은지를 찾을 때 사용합니다.
  • 하지만 실제 코드에서는 "조건을 만족하는 첫 원소"를 찾는 경우가 더 많습니다.
    • 예: 홀수인가?
    • 예: 10으로 나누어 떨어지는가?
    • 예: rarity가 Unique인가?

std::find_if

auto it = std::find_if(v.begin(), v.end(), predicate);
  • predicate(*it)true가 되는 첫 요소를 반환합니다.
  • 못 찾으면 end()를 반환합니다.
  • 성능은 선형 탐색이므로 O(N)입니다.
  • #include <algorithm> 필요.

Predicate 구현 방식

방식설명
함수 포인터전역/정적 함수 전달 (상태 전달 어려움)
함수 객체(펑터)operator()를 가진 타입 (상태 보관 가능)
람다익명 함수 (가독성/지역성 좋아 실무에서 가장 자주 사용)

Predicate 시그니처 감각

  • 핵심은 "요소 1개를 받아 bool 반환"입니다.
  • const T&로 받으면 복사를 줄일 수 있습니다.
bool IsOdd(int n);                      // 기본형은 값 전달도 무난
bool IsUnique(const Item& item);        // 큰 타입은 const 참조 권장

구현 방식별 예시

함수 포인터

bool IsDivisibleBy11(int n) { return n % 11 == 0; }

auto it = std::find_if(v.begin(), v.end(), IsDivisibleBy11);

펑터(상태 보관 가능)

struct HasItemId {
    int wantedId;
    bool operator()(const Item& item) const {
        return item.itemId == wantedId;
    }
};

auto it = std::find_if(inventory.begin(), inventory.end(), HasItemId{2});

람다(실무 기본)

int wantedId = 2;
auto it = std::find_if(inventory.begin(), inventory.end(),
    [wantedId](const Item& item) {
        return item.itemId == wantedId;
    });

인벤토리 실전 패턴 (강의 핵심)

유니크 아이템이 있는지 찾기

struct IsUniqueItem {
    bool operator()(const Item& item) const {
        return item.rarity == Rarity::Unique;
    }
};
auto it = std::find_if(inventory.begin(), inventory.end(), IsUniqueItem());

찾은 뒤 처리

if (it != inventory.end()) {
    // 찾음: *it 사용 가능
} else {
    // 못 찾음
}
  • it == end()인지 확인하기 전 *it 역참조하면 안 됩니다.

왜 find_if가 자주 쓰이나?

  • 게임/서비스 로직은 값 일치보다 "조건 검색"이 훨씬 많습니다.
  • 그래서 find보다 find_if를 더 자주 쓰게 됩니다.

자주 하는 실수 + 체크 질문

자주 하는 실수

실수문제
find_if 결과를 바로 *it 사용못 찾은 경우 end() 역참조로 UB
Predicate에서 큰 객체를 값 복사불필요한 복사 비용 증가
조건 로직이 긴데 람다에 모두 몰아넣음가독성 저하 (함수/펑터 분리 고려)
캡처를 [&]로 남발수명/의도 불명확으로 버그 위험

체크 질문 (스스로 답해보기)

  • findfind_if의 목적 차이를 말할 수 있는가?
  • find_if 반환값을 안전하게 처리하는 패턴을 설명할 수 있는가?
  • 상태가 필요한 조건 검색에서 펑터와 람다 중 무엇을 선택할지 기준이 있는가?

profile
李家네_공부방

0개의 댓글