Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Test if a lambda is stateless?

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.
like image 879
Skeen Avatar asked Nov 13 '13 18:11

Skeen


1 Answers

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.

like image 165
Nawaz Avatar answered Sep 20 '22 03:09

Nawaz