std::function
a を関数ポインタに変換することはできません(逆にすることもできます)。
少し見回していたところ、バリアディックパックの保存方法に関するこの投稿を見つけました。
そのコードを少し変更してメンバーをstaticにすると、役に立つかもしれません。
namespace helper {
template <std::size_t... Ts>
struct index {};
template <std::size_t N, std::size_t... Ts>
struct gen_seq : gen_seq<N - 1, N - 1, Ts...> {};
template <std::size_t... Ts>
struct gen_seq<0, Ts...> : index<Ts...> {};
}
template <typename... Ts>
class Action {
private:
static std::function<void (Ts...)> f_;
static std::tuple<Ts...> args_;
public:
template <typename F, typename... Args>
static void setAction(F&& func, Args&&... args) {
f_ = std::forward<F>(func);
args_ = std::make_tuple(std::forward<Args>(args)...);
}
template <typename... Args, std::size_t... Is>
static void func(std::tuple<Args...>& tup, helper::index<Is...>) {
f_(std::get<Is>(tup)...);
}
template <typename... Args>
static void func(std::tuple<Args...>& tup) {
func(tup, helper::gen_seq<sizeof...(Args)>{});
}
static void act() {
func(args_);
}
};
// Init static members.
template <typename... Ts> std::function<void (Ts...)> Action<Ts...>::f_;
template <typename... Ts> std::tuple<Ts...> Action<Ts...>::args_;
上記のコードを使用すると、任意の関数または関数オブジェクトを実行時に指定された任意のパラメーターAction
と共に格納し、パラメーターをとらないその静的メンバー関数を使用しact()
て、以前に指定したパラメーターで格納された関数を呼び出すことができます。
act()
変換可能なのでvoid (*)()
、コールバック関数に渡すことができます。
以下が機能するはずです。
auto someCallable = [] (int x) { std::cout << "Number " << x << std::endl };
Action<int>::setAction(someCallable, 1); // Pass func and parameters.
glutIdleFunc(Action<int>::act);