Descobri que os lvalue
fechamentos lambda sempre podem ser passados como rvalue
parâmetros de função.
Veja a seguinte demonstração simples.
#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;
}
O caso 2 é o comportamento padrão (usei apenas um std::function
para fins de demonstração, mas qualquer outro tipo se comportaria da mesma maneira).
Como e por que o caso 1 funciona? Qual é o estado de fn1
fechamento após o retorno da função?
std::function
ser deduzidos de um lambda". Seu programa não tenta deduzir os argumentos do modelo std::function
, portanto, não há problema com a conversão implícita.
std::function
possui um construtor não explícito que aceita fechamentos lambda, portanto, há conversão implícita. Mas nas circunstâncias da questão vinculada, a instanciação de modelo de std::function
não pode ser inferida a partir do tipo lambda. (Por exemplo, std::function<void()>
pode ser construído a partir de [](){return 5;}
um tipo de retorno não nulo.
fn1
é implicitamente convertido em umstd::function
infoo(fn1)
. Essa função temporária é então um rvalue.