2005-10-22
find_if 와 boost::lambda
STL 컨테이너를 만지작거리다보면 종종 algorithm 을 써서 코드를 간략하게 표현하고픈 충동이 든다. 그런데 STL에서 제공하는 각종 function template 의 파워는 생각보다 약하다. 가령 다음과 같이 컨테이너 내부 객체의 멤버 함수의 실행 결과를 기준으토 무언가를 하고 싶은 경우...
class Focker
{
public :
Focker(int v) : value(v) {}
int GetValue() const { return value; }
private:
int value;
};
typedef list FOCKERS;
FOCKERS fockers;
fockers.push_back( Focker(1) );
fockers.push_back( Focker(2) );
fockers.push_back( Focker(3) );
fockers.push_back( Focker(4) );
fockers.push_back( Focker(5) );
// how to find whose value ==3 ??
가장 단순한 방법으로는 하드코딩 함수자를 사용하면 된다.
class GetValueIs3
{
public :
GetValueIs3(){}
bool operator() ( const Focker & f ) const
{
return f.GetValue() == 3;
}
};
FOCKERS::iterator itr;
itr = find_if( fockers.begin(), fockers.end(), GetValueIs3() );
assert( itr != fockers.end() );
cout GetValue() GetValue() (),3),
mem_fun_ref(&Focker::GetValue )) );
그래서 이걸 가능하게 하기 위해서 몇 시간동안 씨름하다가 mem_fun_ref 의 코드를 살짝 고쳐서 다음과 같은 코드를 만들어봤다.
template
class my_const_mem_fun_ref_t
: public unary_function
{
public:
explicit my_const_mem_fun_ref_t(_Result (_Ty::*_Pm)() const, const _Fn & f )
: _Pmemfun(_Pm), func(f)
{
}
typename _Fn::result_type operator()(const _Ty& _Left) const
{
return (func((_Left.*_Pmemfun)()));
}
private:
_Result (_Ty::*_Pmemfun)() const; // the member function pointer
_Fn func;
};
template
inline
my_const_mem_fun_ref_t
my_mem_fun_ref(_Result (_Ty::*_Pm)() const, const _Fn & f)
{
return (my_const_mem_fun_ref_t(_Pm,f));
}
itr = find_if( fockers.begin(), fockers.end(),
my_mem_fun_ref( &Focker::GetValue, bind2nd(equal_to(),3) )
);
assert( itr != fockers.end() );
cout GetValue() GetValue()