현재까지 제안된 방법이 최선일까? 앞서 이야기하기도 했지만 절대 그렇지 않을 것이다. 더 다양한 방법이 있을 수 있을 것이다. 본 포스트에는 좀 더 나은 방법에 대해 기록하며, 그 이외의 다양한 이야기를 적어둘 것이다.
콜백함수를 위한 템플릿을 이용한 2개의 클래스를 사용하는 것 보다 괜찮아 보이는 방법 중 하나는 ‘함수 어댑터(function adaptor)’를 사용하는 방법이다(출처).
// binding function 제작
#include <iostream>
#include <cstddef>
// 콜백 함수
struct demo
{
void func() { std::cout << "called.n"; }
};
template <typename obj, void (obj::*xptr)() >
struct func_bind
{
static obj x;
static void call() { (x.*xptr)(); }
};
template <typename obj, void (obj::*xptr)(void) >
obj func_bind::x;
// 전역변수 콜백 함수 포인터.
// 어떤 라이브러리 어딘가에 있다고 가정한다.
void (*g_callback)(void) = NULL;
int main(int argc, char** argv)
{
// 라이브러리에 우리의 콜백 함수를 등록하는 과정이라고 가정한다.
func_bind<demo, &demo::func> bound;
g_callback = bound.call;
g_callback();
return EXIT_SUCCESS;
}
[그 외 이야기들]
함수 어댑터
멤버 함수를 위한 STL 함수 어댑터들이 있다.mem_fun_ref, mem_fun 들이 그것이다.
#include <functional>
demo d; // 멤버 변수를 가진 클래스
std::mem_fun_t<void, demo> p = std::mem_fun<void, demo>(&demo::func);
std::mem_fun_ref_t<void, demo> r = std::mem_fun_ref<void, demo>(&demo::func);
p(&d); // demo::func 멤버 함수 호출
r(d); // 위와 같으나 위는 객체의 포인터, 이것은 객체의 레퍼런스를 인자로 받는다.
선언된 p나 r은 C-Style callback의 인자로는 사용할 수 없다.
[GLUT Wrapper 등]
- G. Stetten 과 K.Crawford는 GLUT의 C++ wrapper 인 GlutMaster를 만들었다. (홈페이지)
- N. Stewart는 OpenGL C++ Toolkit를 공개했다. (홈페이지)
[Function Object]
- mem_fun, mem_fun_ptr 등은 functional 헤더에 정의되어 있다. 이 외에도 STL은 많은 함수 어댑터를 제공한다. 이들을 이용해 함수형 프로그래밍이 가능하다.
- Boost library는 함수형 프로그래밍 뿐 아니라 C++ 프로그래밍에 있어 유용한 많은 기능을 제공한다. Boost에 대해서는 차후 따로 포스팅할 계획이다.
차례로 돌아가기