Necesito un rasgo de tipo para detectar si alguno de los parámetros de función de un argumento de plantilla es una referencia. Este código funciona, el rasgo es "is_any_param_reference" y static_assert se activa, la firma de foo cambia de void foo( std::string s, int i) a void foo( std::string& s, int i) (primero parámetro convertido a referencia).
Pero la identificación no funcionó con lambdas... No se compila si uso:
int main() { auto foo2 = [](std::string s, int i){ std::cout << s << " " << i << std::endl; }; some_function( foo2, s, i ); }¿Alguna idea de cómo generar un tipo de rasgos que funcione también para lambda?
¡¡Gracias!!
#include <iostream> #include <string> #include <type_traits> using namespace std; template<typename ... A> struct any_is_reference : std::false_type {}; template<typename A, typename ... P> struct any_is_reference<A, P...>: std::conditional_t< std::is_reference<A>::value , std::true_type, any_is_reference<P...> >::type{}; template<typename Sig> struct is_any_param_reference; template<typename R, typename...Args> struct is_any_param_reference<R(*)(Args...)>: any_is_reference<Args...>{}; template< typename Sig > inline constexpr bool is_any_param_reference_v = is_any_param_reference<Sig>::value; template< typename F , typename ... Args> void some_function( F f, Args... args) { static_assert(!is_any_param_reference< F >::value, "FUNCTION MUST NOT HAVE PARAMETERS BY REFERENCE"); f(args...); } void foo( std::string s, int i) { std::cout << s << " " << i << std::endl; } int main() { const std::string s = "Hello"; int i = 0; some_function(foo, s, i); }template<typename T> struct is_any_param_reference : is_any_param_reference<decltype(&T::operator())>{}; template<typename R, typename...Args> struct is_any_param_reference<R(*)(Args...)>: any_is_reference<Args...>{}; template<typename T, typename R, typename...Args> struct is_any_param_reference<R(T::*)(Args...)>: any_is_reference<Args...>{}; template<typename T, typename R, typename...Args> struct is_any_param_reference<R(T::*)(Args...) const>: any_is_reference<Args...>{}; La plantilla principal asume que su argumento es una clase que proporciona operator() (por ejemplo, una lambda). Luego hay especializaciones para un puntero de función simple, así como una función de puntero a miembro. La plantilla primaria delega efectivamente a esta última especialización.