Ho scoperto che lvalue
le chiusure lambda possono sempre essere passate come rvalue
parametri di funzione.
Vedi la seguente semplice dimostrazione.
#include <iostream>
#include <functional>
using namespace std;
void foo(std::function<void()>&& t)
{
}
int main()
{
// Case 1: passing a `lvalue` closure
auto fn1 = []{};
foo(fn1); // works
// Case 2: passing a `lvalue` function object
std::function<void()> fn2 = []{};
foo(fn2); // compile error
return 0;
}
Il caso 2 è il comportamento standard (ho appena usato un std::function
a scopo dimostrativo, ma qualsiasi altro tipo si comporterebbe lo stesso).
Come e perché funziona il caso 1? Qual è lo stato di fn1
chiusura dopo la restituzione della funzione?
std::function
possibile dedurre argomenti di template da una lambda". Il programma non tenta di dedurre gli argomenti del modello di std::function
, quindi non vi sono problemi con la conversione implicita.
std::function
ha un costruttore non esplicito che accetta le chiusure lambda, quindi esiste una conversione implicita. Ma nelle circostanze della domanda collegata, l'istanza del modello di std::function
non può essere dedotta dal tipo lambda. (Ad esempio, std::function<void()>
può essere costruito [](){return 5;}
anche se ha un tipo di ritorno non vuoto.
fn1
è implicitamente convertito in unstd::function
infoo(fn1)
. Quella funzione temporanea quindi è un valore.