I want to get return type and parameter type of a lambda. Is it possible to figure out the parameter type and return type of a lambda?give a solution.But it does not work for generic lambda.
template<typename F>
struct function_traits :public
function_traits<decltype(&F::operator())> {};
template<typename R,typename C,typename... Args>
struct function_traits<R(C::*)(Args...)const>:public
function_traits<R(Args...)>{
constexpr static size_t arity = sizeof...(Args);
};
auto f1 = [](int x) {return x+1; };
Print(function_traits<decltype(f1)>::arity); //return 1
auto f2 = [](auto x) {return x+1; };
Print(function_traits<decltype(f2)>::arity); //error
So how to solve it to get return type and parameter type of a generic lambda?
Generic lambdas are lambdas where the operator() overload is a template function. If a template function's parameter is deduced, then it has no type; only an individual instantiation of such a template has a parameter with a type.
auto isn't a type; it's a placeholder that means "this is a template parameter".
Lambdas are not in any way functions.
The compiler treats f1 and f2 as if they were classes with call operators.
Some lambdas have implicit conversion operators to function pointers.
Here is a link to what those two look like in cppinsights.
BTW, I highly recommend using cppinsights if you are new to C++ templates. Here is a great video talking about it, and here is one where he uses cppinsights to explore lambdas in depth.
I have also copied the relevant code here for explanation, and in case the link every goes away.
This is what your f1 looks like.
class __lambda_1_11
{
public:
inline /*constexpr */ int operator()(int x) const
{
return x + 1;
}
using retType_1_11 = int (*)(int);
inline /*constexpr */ operator retType_1_11 () const noexcept
{
return __invoke;
};
private:
static inline int __invoke(int x)
{
return x + 1;
}
};
and this is what your f2 looks like.
class __lambda_2_11
{
public:
template<class type_parameter_0_0>
inline /*constexpr */ auto operator()(type_parameter_0_0 x) const
{
return x + 1;
}
private:
template<class type_parameter_0_0>
static inline auto __invoke(type_parameter_0_0 x)
{
return x + 1;
}
};
Note that f1 has a non-template call operator and it has an implicit conversion operator to a function pointer (int (*)(int)).
f2 has a template call operator and does not have an implicit conversion operator - because the call operator is a member function template.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With