Is it possible to constrain the type of capture of a lambda given as parameter ?
For example, Is it possible to take only lambdas that don't capture anything by reference ?
template <typename F>
void f(const F& lambda) // F must be a lambda that do not capture by ref
{
:::
}
A lambda is a syntax for creating a class. Capturing a variable means that variable is passed to the constructor for that class. A lambda can specify whether it's passed by reference or by value.
Significance of Lambda Function in C/C++Lambda Functions can also be used as a value by the variable to store. Lambda can be referred to as an object that can be called by the function (called functors).
But a lambda cannot be recursive, it has no way to invoke itself. A lambda has no name and using this within the body of a lambda refers to a captured this (assuming the lambda is created in the body of a member function, otherwise it is an error).
Can you create a C++11 thread with a lambda closure that takes a bunch of arguments? Yes – just like the previous case, you can pass the arguments needed by the lambda closure to the thread constructor.
MSalters notes that "non-capturing lambda's can be converted to a pointer-to-function." What does this mean? The lambda object will match a pointer to function parameter type.
It's tricky to translate the lambda type to a pointer-to-function. Here is my attempt at a compliant implementation. It's slightly hackish.
#include <type_traits>
template< typename fn >
struct ptmf_to_pf;
template< typename r, typename c, typename ... a >
struct ptmf_to_pf< r (c::*) ( a ... ) const >
{ typedef r (* type)( a ... ); };
// Use SFINAE to hide function if lambda is not convertible to function ptr.
// Only check that the conversion is legal, it never actually occurs.
template< typename lambda >
typename std::enable_if< std::is_constructible<
typename ptmf_to_pf< decltype( &lambda::operator() ) >::type,
lambda >::value >::type
f( lambda arg ) {
arg( "hello " );
arg( "world\n" );
}
#include <iostream>
int main() {
int x = 3;
f( []( char const *s ){ std::cout << s; } ); // OK
f( [=]( char const *s ){ std::cout << s; } ); // OK
f( [=]( char const *s ){ std::cout << s << x; } ); // error
}
This will not accept function pointers as direct arguments, since the template parameter needs to resolve to a functor. You could make it do so by providing a specialization for ptmf_to_pf
that accepts pointer to function types.
Also, as the demo shows, it won't accept lambdas that capture anything by value, as well as by reference. There is no way in C++ to make the restriction so specific.
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