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.
An option could be to explicitly look a the size of the type, a stateless should in principle have the same size as other stateless types (I picked
std::true_type
for a reference type).I don't know how portable this solution is. In any case check my other solution: https://stackoverflow.com/a/34873139/225186
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.And here is the test code:
Output:
Online Demo.
Does not work for polymorphic lambdas, require as a precondition that the argument be a closure type. (E.g.
is_captureless_lambda<int>
isstd::true_type
.)Boost.TypeTraits
is_stateless
seems to do the job for whatever reason without much drama:boost::is_stateless
is simple the combination of other conditions, it can be expressed in terms of standard type traits I suppose:http://www.boost.org/doc/libs/1_60_0/libs/type_traits/doc/html/boost_typetraits/reference/is_stateless.html
Check my other answer based on
sizeof
: https://stackoverflow.com/a/34873353/225186Per § 5.1.2/6
If it's convertible to a pointer to function, then MAYBE it has to not capture anything (stateless). In action:
You can also use
std::is_convertible
: