How would I go about testing if a lambda is stateless, that is, if it captures anything or not? My guess would be using overload resolution with a function pointer overload, or template specialization?
int a;
auto l1 = [a](){ return 1; };
auto l2 = [](){ return 2; };
// test l1 and l2, get a bool for statelessness.
As per the Standard, if a lambda doesn't capture any variable, then it is implicitly convertible to function pointer.
Based on that, I came up with is_stateless<>
meta-function which tells you whether a lambda is stateless or not.
#include <type_traits>
template <typename T, typename U>
struct helper : helper<T, decltype(&U::operator())>
{};
template <typename T, typename C, typename R, typename... A>
struct helper<T, R(C::*)(A...) const>
{
static const bool value = std::is_convertible<T, R(*)(A...)>::value;
};
template<typename T>
struct is_stateless
{
static const bool value = helper<T,T>::value;
};
And here is the test code:
int main()
{
int a;
auto l1 = [a](){ return 1; };
auto l2 = [](){ return 2; };
auto l3 = [&a](){ return 2; };
std::cout<<std::boolalpha<<is_stateless<decltype(l1)>::value<< "\n";
std::cout<<std::boolalpha<<is_stateless<decltype(l2)>::value<< "\n";
std::cout<<std::boolalpha<<is_stateless<decltype(l3)>::value<< "\n";
}
Output:
false
true
false
Online Demo.
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