c_function と lambda expressions を組み合わせる
さて、c_function と lambda expressions の組み合わせについては上記のサイトを参照してもらえれば分かると思います。
c_function を使用する場合、ユニークな型を使用する必要がありますが、それを lambda expressions を使用しようという話ですね。
確かに lambda expressions は decltype([]{}) のように decltype で使用することは出来ませんが、上記の場合だと引数として渡せば解決出来そうなのでやってみました。
[ソース]
template<typename Unique, typename FuncType, typename Func> struct c_function_impl; template<typename Unique, typename Result, typename ...Args, typename Func> struct c_function_impl<Unique, Result(*)(Args...), Func>{ static Result call(Args... args){ return func(args...); } static Func func; }; template<typename Unique, typename Result, typename ...Args, typename Func> Func c_function_impl<Unique, Result(*)(Args...), Func>::func; template<typename Unique, typename FuncType, typename Func> FuncType make_c_function(Func func){ c_function_impl<Unique, FuncType, Func>::func = func; return &c_function_impl<Unique, FuncType, Func>::call; } template<typename FuncType, typename Lambda, typename Func> FuncType make_c_function(Lambda, Func func){ return make_c_function<Lambda, FuncType>(func); } #include <iostream> using func_type = int(*)(); void printer(func_type func){ std::cout << func() << std::endl; } struct value{ int operator ()() const{ return value_; } int value_; }; template<typename T> constexpr int func(T){ return 0; } int main(){ { auto f1 = make_c_function<struct Unique1, int(*)()>(value{1}); auto f2 = make_c_function<struct Unique2, int(*)()>(value{2}); // 間違えて同じ型名を使ってしまった auto f3 = make_c_function<struct Unique2, int(*)()>(value{3}); printer(f1); // 1 printer(f2); // 3 printer(f3); // 3 } { // []{} を渡すだけなので名前を考える必要がない auto f1 = make_c_function<int(*)()>([]{}, value{1}); auto f2 = make_c_function<int(*)()>([]{}, value{2}); auto f3 = make_c_function<int(*)()>([]{}, value{3}); printer(f1); // 1 printer(f2); // 2 printer(f3); // 3 } return 0; }