C関数レベルのクロージャを C++ で実現?
前にlibffi を使ってクロージャが作れることは確認したけど、やや力技過ぎ。
ちょっと調べてみるとid:mb2syncさんの日記 (スターありがとうございました) に c_function というのが紹介されていたので試してみた。
#include <iostream> #include "c_function.hpp" struct my_functor { my_functor(int _c): c(_c) {} int operator()(int a, int b) { return a + b + c; } int c; }; template<int T_> struct uniqueness {}; // WTF! #define GEN_GUID() \ ::uniqueness<(sizeof(__FILE__) * __LINE__> #define MAKE_C_FUNCTION(sig, f) \ ::redshift::base::make_c_function<GEN_GUID(), sig>(f) template<typename Tguid_, typename Tcfun_, typename Tfun_> inline void my_make_c_function(Tcfun_& retval, Tfun_& f) { retval = ::redshift::base::make_c_function<Tguid_, Tcfun_, Tfun_>(f); } #define MY_MAKE_C_FUNCTION(ret, f) \ ::my_make_c_function<GEN_GUID()>(ret, f) int main(int, char**) { my_functor f1(1), f2(2); int(*foo)(int, int); int(*bar)(int, int); MY_MAKE_C_FUNCTION(foo, f1); MY_MAKE_C_FUNCTION(bar, f2); std::cout << foo(1, 2) << std::endl; std::cout << bar(1, 2) << std::endl; return 0; }
インスタンスを区別するために毎回ユニークな型を渡してやらないといけないというところは __FILE__ と __LINE__ でむりくりしのいでみたw だめ?
もちろん同じ行に 2 つ以上 MY_MAKE_C_FUNCTION を書くことはできません。