I'm writing some wrapping code, where an external library calls a c++ function (using variadic templates and such). The crucial point is that the external library requires a c-function, which would normally be fine, as this is legal:
LibraryFuncType fn = [](params) { ... }
While I can easily do this by hand, I would like to automate the wrapping with something like:
function_(context, "name", myfunc);
To do this, I would need a function similar to:
template <ReturnType, ParamTypes...>
static void function_(Context &ctx, const std::string &name, std::function<ReturnType(ParamTypes...)> fn) {
ctx.registerFunction(name, [fn](State *state) -> int {
Context ctx(state);
return apply_helper<sizeof..(ParamTypes)>::apply(ctx, fn);
});
}
where the second parameter "ctx.registerFunction" is of the type LibraryFuncType.
But this of course is problematic, because the lambda conversion is no longer legal due to the capture of 'fn'. However, if I don't capture 'fn', then I won't have access to it in the lambda.
I think the only way to deal with this is to have a static variable, but it's not clear to me the best way to introduce it. The current solution I have is:
template <typename ReturnType, typename... ParamTypes>
struct function_helper {
static std::function<ReturnType(ParamTypes...)> fn;
function_helper(std::function<ReturnType(ParamTypes...)> _fn) {
fn = _fn;
}
static void registerFn(Context &ctx, const std::string &name) {
ctx.registerFn(name, [](state *state) -> int {
Context ctx(state);
return apply_helper<sizeof...<ParamTypes>>::apply(ctx, fn);
});
}
};
template <typename ReturnType, typename... ParamTypes>
std::function<ReturnType(ParamTypes...)> function_helper<ReturnType, ParamTypes...>::fn;
template <typename ReturnType, typename... ParamTypes>
void function_(Context &ctx, const std::string &name, std::function<ReturnType(ParamTypes...)> fn) {
function_helper<ReturnType, ParamTypes...> reg(fn);
reg.registerFn(ctx, name);
}
While technically this works, it's clearly dangerous (and hacky), because if I use 'function_helper' on two functions with the same signature, it will set 'fn' incorrectly for one of them.
Additionally, I could do the same dangerous-static variable by just declaring a static variable in 'function_'. I made the class hoping it would lead to some insight into a correct way of getting around the problem.
Does anyone know of a better way of using a lambda that doesn't require a capture (or alternatively, a way of converting a lambda that does capture to a c-function)?