함수 포인터 어댑터

seio·2022년 10월 9일
0

C++ STL

목록 보기
17/17

함수 포인터 어댑터

함수 포인터 어댑터는 일반 함수를 어댑터 적용이 가능한 함수 객체로 변환한다. STL은 ptr_fun()이라는 함수 포인터 어댑터를 제공한다.

//순차열 원소의 개수를 출력하는 count_if() 알고리즘 예제이다. v1 원소 30~40 원소와 그 반대의 원소를 출력하려 한다

bool pred(int n){
	return 30<=n&&n<=40;
}
int main(){
	vector<int> v;// 10,20,30,40,50
    
    //30~40
    count_if(v.begin(),v.end(),pred);
    
    //Error not1은 어댑터로 함수 객체에 argument_type, result_type가 정의돼 있어야함
    count_if(v.begin(),v.end(),not1(pred));
    return 0;
}

count_if(v.begin(),v.end(),pred);는 잘 실행되지만 count_if(v.begin(),v.end(),not1(pred));은 에러이다.

not1(pred)에서 pred가 단항 함수 객체가 아닌 일반 함수이므로 argument_type과 result_type이 정의되어 있지 않기 때문에 어댑터인 not1() 적용이 불가능하다.

//일반 함수에 ptr_fun() 어댑터를 사용하여 함수 객체로 변환하고 not1() 어댑터를 적용한 count_if() 알고리즘 예제

bool pred(int n){
	return 30<=n&&n<=40;
}
int main(){
	vector<int> v;// 10,20,30,40,50
    
    //30~40
    count_if(v.begin(),v.end(),pred);
    
    count_if(v.begin(),v.end(),not1(ptr_fun(pred)));
    return 0;
}

이제 일반 함수 pred는 ptr_fun() 어댑터로 argument_type과 result_type가 정의된 함수 객체로 변환한다. 그래서 not1(ptr_fun(pred))는 30이상 40이하가 아닌 원소의 단항 조건자가 된다.

실제 ptr_fun() 어댑터가 어떻게 구현되어 있는지 사용자 버전 Ptr_func()을 구현한다.
//Ptr_func()을 구현


//server
//클래스: ptr_fun()의 함수 객체 클래스. 일반 함수의 함수 객체 클래스
//여러가지 기능을 제공할 수 있다.. argument_type,result_type
template<typename Rtype, typename Atype>
class Ptr_fun_class:public unary_function<Atype,Rtype>
{
	Rtype (*pf)(Atype);
    
    public:
    Ptr_fun_class(Rtype (*_pf)(Atype)):pf(_pf){}
    Rtype operator()(Atype n)const{
    	return pf(n);
    }
}

//일반 함수를 함수 객체로 변환하는 ptr_fun() 함수
template<typename Rtype, typename Atype>
Ptr_fun_class<Rtype, Atype> Ptr_fun(Rtype (*pf)(Atype)){
	return Ptr_fun_class<Rtype,Atype> (pf);
}
bool pred(int n){
	return 30<=n&&n<=40;
}
int main(){
	vector<int> v;// 10,20,30,40,50
    
    //30~40
    count_if(v.begin(),v.end(),pred);
    
    count_if(v.begin(),v.end(),not1(Ptr_fun(pred)));
    return 0;
}

주요 내용

  • 1) Ptr_fun_class 클래스가 일반함수(pred)의 주소를 저장하는 함수 포인터 멤버 변수를 가진다. 이 클래스는 unary_function 클래스를 상속받아 이 클래스의 객체는 어댑터 적용이 가능하게 한다.

  • 2) Ptr_fun() 함수로 일반 함수의 주소(pred)를 인자로 받아 Ptr_fun_class 함수 객체를 생성(변환)하고 반환한다. Ptr_fun() 어댑터 함수가 반환한 객체는 어댑터 적용이 가능한 함수 객체이다.

멤버 함수 포인터 어댑터

멤버 함수 포인터 어댑터는 멤버 함수를 함수 객체로 변환하여 알고리즘이 객체 원소의 멤버 함수를 호출할 수 있게 한다. STL은 다음 두 가지 멤버 함수 포인터 어댑터를 제공한다

  • mem_fun_ref(): 객체로 멤버 함수를 호출
  • mem_fun(): 객체의 주소로 멤버 함수를 호출

//예제

class point{
	int x,y;
    public:
    explicit point(int _x=0, int _y=0):x(_x),y(_y){}
    void print() const{cout<<x<<y<<endl;}
    int getx(){...}
    int gety(){...}
};
 
 void main(){
 	vector<point> v;
    //호출 불가능
    //for_each(v.begin(),v.end(),&point::print);
    //호출 가능
    for_each(v.begin(),v.end(),mem_fun_ref(&point::print));
 
	 return 0;
 }
 

호출 불가능/가능 이유:
for_each() 알고리즘이 함수를 fun(point 객체)와 같이 호출하기 때문이다. 멤버 함수는 point 객체.print()처럼 호출되어야 한다. 이와 같이 호출될 수 있게 함수 객체를 생성(변환)해주는 어댑터가 mem_fun_ref()이다

profile
personal study area

0개의 댓글