Saya menemukan bahwa lvalue
penutupan lambda selalu dapat dilewati sebagai rvalue
parameter fungsi.
Lihat demonstrasi sederhana berikut.
#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;
}
Kasus 2 adalah perilaku standar (saya hanya menggunakan std::function
untuk tujuan demonstrasi, tetapi jenis lainnya akan berperilaku sama).
Bagaimana dan mengapa kasus 1 berfungsi? Bagaimana keadaan fn1
penutupan setelah fungsi kembali?
std::function
diambil dari lambda". Program Anda tidak berupaya menyimpulkan argumen templat std::function
, jadi tidak ada masalah dengan konversi implisit.
std::function
memiliki konstruktor non-eksplisit yang menerima penutupan lambda, sehingga ada konversi implisit. Tetapi dalam keadaan pertanyaan terkait, instantiasi template std::function
tidak dapat disimpulkan dari jenis lambda. (Misalnya std::function<void()>
dapat dibangun dari [](){return 5;}
meskipun memiliki jenis kembali tidak batal.
fn1
secara implisit dikonversi kestd::function
dalamfoo(fn1)
. Fungsi sementara itu adalah nilai.