0. 함수 포인터의 단점
- 시그니처가(타입이) 일치하지 않으면 사용할 수 없다.
- 특정 상태(값)를 가질 수 없음.
1. 함수 객체 (functor)
함수를 호출하는 용도로 사용하는 객체.
2. 문법
class Functor
{
public:
// 연산자 오버로딩
void operator() ()
{
cout << "Functor Test" << endl;
// 맴버 변수를 출력함
cout << _value << endl;
}
public:
int _value;
};
int main()
{
Functor func;
func._value = 10;
func();
}
특정 동작을 수행하는 멤버 함수를 가지는 클래스를 만들어 사용한다.
일반적으로 괄호 연산자를 오버로딩하여 사용하게 된다.
3. 템플릿 문법과 함수 객체
템플릿 문법을 사용하여 함수 객체를 재사용할 수 있다.
struct AddStruct
{
public:
int operator()(int a, int b)
{
return a + b;
}
};
template<typename T>
int Test(int a, int b, T func)
{
return func(a, b);
}
int main()
{
AddStruct func;
Test(10, 20, func);
}
위의 코드를 통해 a와 b를 더하는 역할을 수행했다면, func의 시그니처를 다르게 지정하여 곱하기를 연산할 수도 있다.
struct MultiplyStruct
{
int operator()(int a, int b)
{
return a * b;
}
};
template<typename T>
int Test(int a, int b, T func)
{
return func(a, b);
}
int main()
{
MultiplyStruct func;
Test(10, 20, func);
}
4. 활용
여러 함수 객체를 컨테이너(큐, 벡터, 리스트) 내에 사용하는 상황을 생각해보자
class AddClass
{
public:
int operator()(int a, int b)
{
return a + b;
}
};
class MultiplyClass
{
int operator()(int a, int b)
{
return a * b;
}
};
template<typename T>
int Test(int a, int b, T func)
{
return func(a, b);
}
int main()
{
queue< ? ? ? > q;
}
상황에 따라 AddClass 펑터 혹은 MultiplyClass 펑터를 사용하고자 하면
위의 q의 타입에는 무엇이 와야하는지에 대한 의문이 생길 수 있다.
이럴 때에는 다형성을 사용하여 상위 클래스로 묶어주면 된다.
class Functors
{
public:
};
class AddClass : public Functors
{
public:
int operator()(int a, int b)
{
return a + b;
}
};
class MultiplyClass : public Functors
{
int operator()(int a, int b)
{
return a * b;
}
};
template<typename T>
int Test(int a, int b, T func)
{
return func(a, b);
}
int main()
{
queue<Functors> q;
}
'복습' 카테고리의 다른 글
오른값 참조 (r-value Reference) (0) | 2023.10.11 |
---|---|
람다 표현식 (Lambda) (0) | 2023.10.11 |
함수 포인터 (0) | 2023.10.06 |
우선순위 큐 (priority_queue) (1) | 2023.10.05 |
가위 바위 보 (0) | 2023.08.07 |