I need to pass a Lambda as callback (in particular for WinAPI). The idea is the following:
-
Store the lambda in a singleton class (every Lambda, also two identical ones, have different types) so it should be safe
LambdaSingleton<Lambda_Type>::instance = l; -
Pass as callback the address of static method that invokes the lambda instance.
template < typename Lambda, typename Callback_Signature_R, typename... Callback_Signature_Args> struct LambdaCallbackSupport{ /** * Callback method * * @param args * The parameters to feed to the lambda * @return * The return value of the execution of the lambda */ static Callback_Signature_R __stdcall callback(Callback_Signature_Args... args){ return LambdaSingleton<Lambda>::instance(args); } };
I already have a working class for extracting informations about functions at compile time es:
template<
typename C,
typename R,
typename... Args>
struct Traits<R(__stdcall *)(Args...) const>{
//various typedefs for R, tuple of args, arity etc..
};
So i would get something like this:
//Example lambda
int toBeCaptured = 8;
auto lambda =
[&](std::string& str) -> size_t{
return toBeCaptured + str.length();
};
typedef decltype(lambda) Lambda;
//Expected callback signature
typedef size_t(__stdcall *CallbackSignature)(std::string&);
//Configure a callback support and pass its method
typedef Traits<CallbackSignature> callbackTraits;
typedef LambdaCallbackSupport<
Lambda,
callbackTraits::Result_Type,
callbackTraits::Args_Tuple_Pack> CallbackSupportType;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //How to unpack the tuple without actually have the arguments??
//Store the lambda instance statically
Singleton<Lambda>::instance = lambda;
//Pass the callback
void* pFunc = &CallbackSupportType::callback;
//Simulate invocation of callback
std::string str("may work?");
size_t ret = (*pFunc)(str);
Since i need only to let the compiler generate a callback class specialization (and not actually invoke its method) how can i apply the iterative unpacking technique proposed in other questions on this site?
Thank you
As a general answer to your question (how to do tuple unpacking), parameter packs can only be generated implicitly in the context of template argument type deduction, so if you want to “unpack” a type
tuple<T1, ..., Tn>into a sequence of typesT1, ..., Tnyou have to instantiate that tuple and supply that instance in input to some function template:However, considering what you want to achieve (get a WinAPI callback from a lambda), I would not rely on tuples, and rather use a free function template. That can be done without introducing many levels of indirections and wrappers. Here is a possible simple solution:
This is the framework. And this is how you would use it:
If you don’t mind macros and want to simplify that further for some usage patterns (like the one above), you can add a macro like this:
That would change your
main()function into the following: