MSalters отмечает, что «лямбда без захвата может быть преобразована в указатель на функцию».Что это значит?Лямбда-объект будет соответствовать указателю на тип параметра функции.
Сложно преобразовать лямбда-тип в указатель на функцию.Вот моя попытка совместимой реализации.Это немного хакерски.
#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
}
Это не примет указатели функций в качестве прямых аргументов, так как параметр шаблона должен преобразовываться в функтор.Вы можете сделать это, предоставив специализацию для ptmf_to_pf
, которая принимает указатель на типы функций.
Кроме того, как показывает демонстрация, он не будет принимать лямбда-выражения, которые собирают что-либо по значению, а такжессылка.В C ++ нет способа сделать это ограничение таким конкретным.