list<Widget*> widgetPts;
bool isInteresting(const Widget* pw);
list<Widget*>::iterator i = find_if( widgetPtrs.begin(),
widgetPtrs.end(),
isInteresting);
if( i != widgetPtrs.end() )
{
….
}
list<Widget*>::iterator i = find_if( widgetPtrs.begin(),
widgetPtrs.end(),
not1(isInteresting));
list<Widget*>::iterator i = find_if( widgetPtrs.begin(),
widgetPtrs.end(),
not1(ptr_fun(isInteresting)));
STL의 4대 표준 함수 어댑터(not1, not2, bind1st, bind2nd)는 모두 특정 typedef가 있어야 하고 STL과 호환하는 비표준 어댑터 역시 마찬가지이다. 어댑터에서 요구하는 typedef를 제공하는 함수객체를 어댑터 적용이 가능하다 라고 표현하며 ptr_fun 은 일반 함수 포인터를 어댑터 적용이 가능한 상태로 바꾸어 주는 역할을 하는 것이다.
일단 어뎁터를 직접만드는 내용은 패스.
어쨋거나 이런 어뎁터를 적용가능한 함수객체를 만드는 방법은 직접 typedef를 써서 만들면 피곤하므로 특정 탬플릿을 상속받아 만들면 된다. 바로 std::unary_function과 std::binary_function 이다.
위의 코드에서 볼수 있듯이 상속하는 unary_function, binary_function 의 탬플릿 매개변수가 상속받는 함수객체의 operator() 함수의 매개변수와 리턴하는 변수형이다.
WigetNameCompare가 구조체인 이유는 일반적으로 내부 상태 데이터가 없는 함수객체의 경우 구조체로 선언하는 것이다.
그리고
어쨋거나 이런 어뎁터를 적용가능한 함수객체를 만드는 방법은 직접 typedef를 써서 만들면 피곤하므로 특정 탬플릿을 상속받아 만들면 된다. 바로 std::unary_function과 std::binary_function 이다.
template<typename T>
class MeetsThreshold : public std::unary_function<Widget, bool>{
private:
const T threshold;
public:
MeetsThreshold(const T& threshold);
bool operator()(const Widget&) const;
….
};struct WigetNameCompare : std::binary_function<Widget,Widget,bool>
{
bool operator()(const Widget& lhs, const Widget& rhs) const;
};
WigetNameCompare가 구조체인 이유는 일반적으로 내부 상태 데이터가 없는 함수객체의 경우 구조체로 선언하는 것이다.
그리고
binary_function<Widget,Widget,bool> bool operator()(const Widget& lhs, const Widget& rhs) const; |
에서 보는것 처럼 unary_function, binary_function 는 operator()가 받는 매개변수의 타입이 비포인터 타입인 경우 const 와 참조자 표시는 빼는것이 상례이다.
ex) const Widget& -> Widget
ex) const Widget& -> Widget
그런데 operator()가 포인터를 매개 변수로 받는 경우에는 unary_function, binary_function 의 템플릿 매개변수와 operator()의 매개변수 타입이 동일하다.
struct PtrWidgetNameCompare:
std::binary_function<const Widget*, const Widget* bool>{
bool operator()(const Widget* lhs, const Widget* rhs) const;
};
어쨋거나 결론은 함수객체를 만들때는 위와 같은 클래스를 상속받아 어뎁터적용이 가능한 객체를 만드는것이 요긴하다 라는 것이다.