J'ai trouvé que lvalue
les fermetures lambda peuvent toujours être passées en tant que rvalue
paramètres de fonction.
Voir la démonstration simple suivante.
#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;
}
Le cas 2 est le comportement standard (je viens d'utiliser un std::function
à des fins de démonstration, mais tout autre type se comporterait de la même manière).
Comment et pourquoi fonctionne le cas 1? Quel est l'état de fn1
fermeture après le retour de la fonction?
std::function
être déduits d'un lambda". Votre programme n'essaie pas de déduire les arguments du modèle de std::function
, il n'y a donc pas de problème avec la conversion implicite.
std::function
a un constructeur non explicite qui accepte les fermetures lambda, il y a donc une conversion implicite. Mais dans les circonstances de la question liée, l'instanciation du modèle std::function
ne peut pas être déduite du type lambda. (Par exemple, il std::function<void()>
peut être construit à partir [](){return 5;}
même s'il a un type de retour non nul.
fn1
est implicitement converti en unstd::function
infoo(fn1)
. Cette fonction temporaire est alors une valeur r.