Odkryłem, że lvalue
zamknięcia lambda zawsze można przekazać jako rvalue
parametry funkcji.
Zobacz następującą prostą demonstrację.
#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;
}
Przypadek 2 to standardowe zachowanie (właśnie użyłem std::function
do celów demonstracyjnych, ale każdy inny typ zachowałby się tak samo).
Jak i dlaczego działa przypadek 1? Jaki jest stan fn1
zamknięcia po zwróceniu funkcji?
std::function
można wywnioskować argumentów z lambda”. Twój program nie próbuje wywnioskować argumentów szablonu std::function
, więc nie ma problemu z niejawną konwersją.
std::function
ma nieprecyzyjny konstruktor, który akceptuje zamknięcia lambda, więc zachodzi niejawna konwersja. Ale w okolicznościach połączonego pytania std::function
nie można wywnioskować z wystąpienia lambda typu szablonu . (Na przykład std::function<void()>
można skonstruować z [](){return 5;}
tego, że ma on nieważny typ zwrotu.
fn1
domyślnie jest konwertowany nastd::function
infoo(fn1)
. Ta tymczasowa funkcja jest wtedy wartością rvalue.