ฉันพบว่าการlvalue
ปิดแลมบ์ดาสามารถส่งผ่านเป็นrvalue
พารามิเตอร์ฟังก์ชันได้เสมอ
ดูการสาธิตง่ายๆดังต่อไปนี้
#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;
}
กรณีที่ 2 เป็นพฤติกรรมมาตรฐาน (ฉันเพิ่งใช้std::function
เพื่อวัตถุประสงค์ในการสาธิต แต่ประเภทอื่น ๆ จะทำงานเหมือนกัน)
เคส 1 ทำงานอย่างไรและทำไม? สถานะการfn1
ปิดหลังจากฟังก์ชั่นกลับมาคืออะไร?
std::function
อนุมานจากแลมบ์ดา" โปรแกรมของคุณไม่พยายามสรุปอาร์กิวเมนต์ของเทมเพลตstd::function
ดังนั้นจึงไม่มีปัญหากับการแปลงโดยนัย
std::function
มีคอนสตรัคต์ที่ไม่ชัดเจนซึ่งยอมรับการปิดแลมบ์ดาดังนั้นจึงมีการแปลงโดยนัย แต่ในสถานการณ์ของคำถามที่เชื่อมโยงการสร้างอินสแตนซ์ของเทมเพลตstd::function
ไม่สามารถอนุมานได้จากประเภทแลมบ์ดา (ตัวอย่างstd::function<void()>
สามารถสร้างได้จาก[](){return 5;}
แม้ว่ามันจะมีประเภทผลตอบแทนที่ไม่เป็นโมฆะ
fn1
ถูกแปลงโดยปริยายไปในstd::function
foo(fn1)
ฟังก์ชั่นชั่วคราวนั้นเป็นค่า rvalue