Descubrí que los lvalue
cierres lambda siempre se pueden pasar como rvalue
parámetros de función.
Vea la siguiente demostración simple.
#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;
}
El caso 2 es el comportamiento estándar (acabo de utilizar un std::function
para fines de demostración, pero cualquier otro tipo se comportaría igual).
¿Cómo y por qué funciona el caso 1? ¿Cuál es el estado de fn1
cierre después de que la función regresó?
std::function
pueden deducirse los argumentos de plantilla de una lambda?". Su programa no intenta deducir los argumentos de la plantilla std::function
, por lo que no hay problema con la conversión implícita.
std::function
tiene un constructor no explícito que acepta cierres lambda, por lo que hay una conversión implícita. Pero en las circunstancias de la pregunta vinculada, la instanciación de plantilla de std::function
no se puede inferir del tipo lambda. (Por ejemplo, std::function<void()>
se puede construir [](){return 5;}
a pesar de que tiene un tipo de retorno no nulo.
fn1
se convierte implícitamente a unastd::function
enfoo(fn1)
. Esa función temporal es entonces un valor r.