더 다양한 스터디

현재까지 제안된 방법이 최선일까? 앞서 이야기하기도 했지만 절대 그렇지 않을 것이다. 더 다양한 방법이 있을 수 있을 것이다. 본 포스트에는 좀 더 나은 방법에 대해 기록하며, 그 이외의 다양한 이야기를 적어둘 것이다.

콜백함수를 위한 템플릿을 이용한 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에 대해서는 차후 따로 포스팅할 계획이다.

차례로 돌아가기