¿Es posible obtener un puntero de función (miembro) a una instancia específica de un lambda genérico?
Sé que puedo hacerlo para lambdas estándar que no capturan, y para plantillas abreviadas, pero parece que no puedo obtener un puntero de función miembro para la función miembro del operador de llamada operator() instanciada explícitamente del tipo inventado para el genérico lambda.
#include <iostream> void f1( auto v) { std::cout << v << std::endl; } int main() { void (*pf)(int) = f1<int>; // OK void (*pf2)(int) = [](int v) { std::cout << v << std::endl; } ; // OK [](auto v) { std::cout << v << std::endl; }.operator() < int > (42); // OK auto generic_template = [](auto v) { std::cout << v << std::endl; } ; using generic_type = decltype (generic_template); // void (generic_type::*pf3)(int) = &generic_type::operator()<int>; // fails to compile pf(5); }El interés aquí es académico.
Editar:
Como nota de interés para futuros lectores, las soluciones ofrecidas a esta pregunta también se aplican a la obtención de punteros de función para lambdas con captura, además de lambdas genéricas. Por ejemplo, en base a las respuestas:
auto generic_lambda = [](auto v) { std::cout << v << std::endl; } ; using generic_type = decltype (generic_lambda); void (generic_type::*pf1)(int) const = &generic_type::operator(); (&generic_lambda->*pf1)(43); // OK int x = 5; auto capturing_lambda = [x](int v) { std::cout << v+x << std::endl; } ; using capturing_type = decltype (capturing_lambda); void (capturing_type::*pf2)(int) const = &capturing_type::operator(); (&capturing_lambda->*pf2)(43); // OKSí, y puede omitir los argumentos de la plantilla si se pueden deducir del tipo que se está inicializando (o del tipo de resultado de una conversión), pero dado que la lambda no es mutable , la función miembro es const y, por lo tanto, debe ser el puntero a- miembro.
¿Es posible obtener un puntero de función (miembro) a una instancia específica de un lambda genérico?
El operator() está calificado const de forma predeterminada, debe agregar const al tipo de puntero de función miembro
void (generic_type::*pf3)(int) const = &generic_type::operator(); Y dado que pf3 es un puntero de función miembro, tenga en cuenta que necesita un objeto lambda específico y usa .* o ->* para invocar.
(generic_template.*pf3)(42);