2008-11-05 4 views
14

값을 찾을 수있는 함수가 있습니다.C++ (STL)에서 펑터를 무효화하려면 어떻게해야합니까?

struct FindPredicate 
{ 

    FindPredicate(const SomeType& t) : _t(t) { 
    } 
    bool operator()(SomeType& t) { 
     return t == _t; 
    } 

private: 
    const SomeType& _t; 
}; 

bool ContainsValue(std::vector<SomeType>& v, SomeType& valueToFind) { 
    return find_if(v.begin(), v.end(), FindPredicate(valueToFind)) != v.end(); 
} 

이제 벡터의 모든 멤버가 해당 조건을 충족하는지 확인하는 함수를 작성하고 싶습니다.

bool AllSatisfy(std::vector<SomeType>& v) { 
    /* ... */ 
} 

한 가지 해결책은 std::count_if 알고리즘.

누구든지 술어를 부정하는 것과 관련된 해결책을 알고 있습니까?

답변

20

가장 좋은 해결책은 STL functional library입니다. 귀하의 술어를 unary_function<SomeType, bool>에서 파생 시키면, 정확히 당신이 필요로하는 (즉, 단항 술어를 부정하는) not1 함수를 사용할 수 있습니다.

struct FindPredicate : public unary_function<SomeType, bool> 
{ 
    FindPredicate(const SomeType& t) : _t(t) {} 

    bool operator()(const SomeType& t) const { 
     return t == _t; 
    } 

private: 
    const SomeType& _t; 
}; 

bool AllSatisfy(std::vector<SomeType>& v, SomeType& valueToFind) 
{ 
    return find_if(v.begin(), 
        v.end(), 
        not1(FindPredicate(valueToFind))) == v.end(); 
} 

가 자신의 솔루션 (인, 이럴 아닌 최선의 선택 ...), 음, 당신이 쓸 수를 롤백하려면 : 여기

당신이 그렇게 할 수있는 방법입니다 첫 번째의 부정 또 다른 조건 :

struct NotFindPredicate 
{ 

    NotFindPredicate(const SomeType& t) : _t(t) { 
    } 
    bool operator()(SomeType& t) { 
     return t != _t; 
    } 

private: 
    const SomeType& _t; 
}; 

bool AllSatisfy(std::vector<SomeType>& v) { 
    return find_if(v.begin(), 
        v.end(), 
        NotFindPredicate(valueToFind)) == v.end(); 
} 

또는 당신은 잘 할과 같은 템플릿 펑터의 부정을 작성할 수

0 당신은 다음과 같이 사용할 수

: 당신은 당신이 원하는 모든 펑와 하지 구조체를 재사용 할 수 있기 때문에 물론

bool AllSatisfy(std::vector<SomeType>& v, SomeType& valueToFind) 
{ 
    FindPredicate f(valueToFind); 
    return find_if(v.begin(), v.end(), Not<FindPredicate>(f)) == v.end(); 
} 

는 후자의 솔루션은 더 좋다.

+0

그리고 당신은 심 템플릿 기능을 추가 할 수 있습니다. – xtofl

7

표준 라이브러리 함수기 not1을 보면, 반환 할 함수기가 무엇이든간에 논리적 인 함수기를 반환합니다.

당신은 같은 것을 할 수 있어야한다 :

bool AllSatisfy(std::vector<SomeType>& v, SomeType& valueToFind) { 
    return find_if(v.begin(), v.end(), not1(FindPredicate(valueToFind))) != v.end(); 
} 
2

가 단순히 not을 호출되지 않은 이유가 궁금 내가 not1 사용 처음.

그 대답은 나에게 조금 놀랐다.

+0

분명히 'not'는'!'기호의 예약 된 대체 표현입니다 (표준 [lex.key]의 2.11.2 절). – Motti

+2

또 다른 이유는 단항 술어 (not1)의 부정과 2 진 술어 (not2). –

0

이 예제에서는 FindPredicate functor가 필요하지 않습니다. 예제에서는 동등성 만 테스트하기 때문입니다.

bool all_equal(std::vector<SomeType>& v, SomeType& valueToFind) 
{ 
    return v.end() == find_if(v.begin(), v.end(), std::bind1st (equal_to(), valueToFind)); 
} 

bool all_not_equal(std::vector<SomeType>& v, SomeType &valueToFind) { 
{ 
    return v.end() == find_if(v.begin(), v.end(), std::bind1st (not_equal_to(), valueToFind)); 
} 

그리고이 템플릿을 템플릿으로 만들 수도 있습니다. SGI의 사람들이이 유형의 지정하지 않고도하지 개체를 반환처럼

template< typename InputIterator , typename Predicate > 
bool test_all(InputIterator first, InputIterator last, Predicate pred) 
{ 
    return last == find_if(first, last, pred); 
} 

test_all(v.begin(), v.end(), std::bind1st(not_equals_to_(value))); 
관련 문제