Un lambda non è un puntatore di funzione! Un lambda è un'istanza della classe generata dal compilatore!
Tuttavia, un lambda non cattura può essere convertito in un puntatore a funzione usando il suo operator+
Ecco un esempio:
int main() {
auto lambda = [](int a) { return a; };
func ptr = +lambda; // this would work
return 0;
}
Purtroppo, il operator+
sarà nemmeno lavorare nel tuo caso, perché ha non è stato dichiarato come constexpr, quindi non puoi usarlo in un parametro template.
Una correzione per il tuo caso sarebbe quella di utilizzare una funzione gratuita ... fino a quando N4487 non è accettato, non puoi aspettarti di passare lambda come parametro del modello.
Un'altra soluzione potrebbe essere quella di creare il proprio funtore invece di un lambda:
struct LambdaType {
constexpr LambdaType() = default;
int operator()(int a) {
return run(a);
}
// this is a non-capturing lambda, the operator can be
// in a static function
static int run(int a) {
return a;
}
};
int main() {
LambdaType lambda;
function<&LambdaType::run>(1); // ---> this is working
return 0;
}
questa soluzione non è molto attraente, ma potrebbe essere utile se LambdaType
è nascosto in un file cpp.
Se il vostro obiettivo è solo il compilatore per essere in grado di inline codice, è possibile utilizzare i modelli per passare il lambda intorno:
#include <iostream>
template <typename T>
int function(T foo, int a) {
return foo(a);
}
int main() {
int a;
std::cin >> a;
int b = function([](int a) { return a; }, a);
return b;
}
Dal momento che il compilatore conosce il tipo di T
per ogni instanciation, un buon il compilatore dovrebbe essere in grado di ottimizzare il lambda.
Con clang, la terza opzione ha pronunciato la seguente assemblea:
main: # @main
pushq %rax
leaq 4(%rsp), %rsi
movl std::cin, %edi
callq std::basic_istream<char, std::char_traits<char> >::operator>>(int&)
movl 4(%rsp), %eax # this is the call to the function
addq $8, %rsp
retq
pushq %rax
movl std::__ioinit, %edi
callq std::ios_base::Init::Init()
movl std::ios_base::Init::~Init(), %edi
movl std::__ioinit, %esi
movl $__dso_handle, %edx
popq %rax
jmp __cxa_atexit # TAILCALL
ho usato -std=c++14 -Ofast -march=native
come bandiere.
'funzione (1);' non è 'ok'. I modelli richiedono un tipo o una costante intera come parametri. 'test' non è né E nessuno dei due è 'lambda'. –
DeiDei
è ok, controlla questa risposta http://stackoverflow.com/questions/1174169/function-passed-as-template-argument/2156899#2156899 e puoi provarlo pure – gsf
lambda è già std :: tipo di funzione. Quello che stai facendo sembra funzione)> (1) che non è valido (perché 1 non è una funzione int). –
Striker