# Capturing lambda & templates/typedefs

This topic is 486 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I'm just starting to use lambdas, due to a specific problem I'm trying to solve. So basically I need a lambda with a capture to simulate a function, that is required to store some internal state. To achieve this, I want to overload a function, which currently is defined as follows:

template<typename Return, typename... Args>
using GlobalBindFunction = Return(*)(Args...);

template<typename Return, typename... Args>
void registerBindFunction(GlobalBindFunction<Return, Args...> pFunction)
{
//...
}

Now if I happen to pass in a capturing lambda, I need to call a different overload, and here's where the problem comes in - if it wasn't required to have access to "Return" and "Args...", it would be sufficient to just do:

template<typename Lambda> // typename Return, typename... Args => required
void registerBindFunction(Lambda&& pFunction)
{
//...
}

std::string_view strIdentifier;
auto lambda =
[strIdentifier](CallState& state)
{
// ...
};

registerBindFunction(std::move(lambda));

Most of the code could actually just work with the lambda-object instead of a function-pointer, but I've got no idea how extract the return-value & argument-list this way. Is there any way to define a template-alias like in the function-ptr example?

template<typename Return, typename... Args>
using Lambda = Return(???)(Args...);

I havn't been able to find much out via googling and/or looking at the type of my lambda via intellisense, but does somebody with expertise on lambdas got any idea? Thanks!

##### Share on other sites

To the best of my knowledge there is no standard syntax for lambda types, however given a lambda typename T, one can extract the type information by pulling the structs () operator (I.e. the lambda function):

template<typename T>
struct LambdaFunctionTraits : public LambdaFunctionTraits<decltype(&T::operator())> { };

template<typename C, typename R, typename... A>
struct LambdaFunctionTraits<R(C::*)(A...) const /*1*/ > {
static constexpr UInt32 kArgCount = sizeof...(A);
using ReturnType = R;
using ArgTypes = std::tuple<A...>;
};

// Example usage, F is guarenteed to be a lambda type
template <typename F, typename TRAITS = LambdaFunctionTraits<F>>
void Foo(F&& foo) {
using R = typename TRAITS::ReturnType;
using A = typename TRAITS::ArgTypes;
} 

*1. Note that for mutable lambdas you would probably have to specialize for a non const function callback, but I have not implemented this yet so I can't say for sure.

In case you need the argument list as a parameter pack instead of a tuple (Or whatever intermediate type you chose), you could expand it with a proxy function that would extract the types.

Edited by Migi0027

##### Share on other sites

Thanks, works as intendet Having the Args as tuple isn't exactly what I need (I do require an arg-pack), but right now I can just overload the 2-3 functions being called to expand the tuple:

template<typename Return, typename... Args>
struct GlobalExecuteHelper
{
template<typename Function, typename State, RuntimeCommand::SlotType... I>
static Return Call(Function func, State& state, std::index_sequence<I...>)
{
constexpr auto vCallSlots = CalculateCallSlots<Args...>(0);

return func(getAttribute<Args, std::get<I>(vCallSlots)>(state)...);
}
};

template<typename Return, typename... Args>
struct GlobalExecuteHelper<Return, std::tuple<Args...>> :
public GlobalExecuteHelper<Return, Args...>
{
};

As for the mutable-bit, lambdas shouldn't be mutable in this case anyways; mutable state needs to be explicitely handled by a "state" object, as those functors are being instantiatied by a compiler and can be called from different places.

• ### What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 12
• 15
• 14
• 46
• 22
• ### Forum Statistics

• Total Topics
634055
• Total Posts
3015276
×

## Important Information

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!