Ho scoperto che lvaluele chiusure lambda possono sempre essere passate come rvalueparametri 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::functiona scopo dimostrativo, ma qualsiasi altro tipo si comporterebbe lo stesso).
Come e perché funziona il caso 1? Qual è lo stato di fn1chiusura dopo la restituzione della funzione?
std::functionpossibile 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::functionha 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::functionnon 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::functioninfoo(fn1). Quella funzione temporanea quindi è un valore.