หากคุณต้องการประสิทธิภาพให้ส่งค่าถ้าคุณเก็บไว้
สมมติว่าคุณมีฟังก์ชันที่เรียกว่า "เรียกใช้สิ่งนี้ในเธรด UI"
std::future<void> run_in_ui_thread( std::function<void()> )
ซึ่งรันโค้ดบางอย่างในเธรด "ui" จากนั้นส่งสัญญาณfutureเมื่อเสร็จแล้ว (มีประโยชน์ในกรอบ UI ที่เธรด UI คือตำแหน่งที่คุณควรยุ่งกับองค์ประกอบ UI)
เรามีสองลายเซ็นต์ที่เรากำลังพิจารณา:
std::future<void> run_in_ui_thread( std::function<void()> ) // (A)
std::future<void> run_in_ui_thread( std::function<void()> const& ) // (B)
ตอนนี้เราน่าจะใช้สิ่งเหล่านี้ดังนี้:
run_in_ui_thread( [=]{
// code goes here
} ).wait();
ซึ่งจะสร้างการปิดนิรนาม (แลมบ์ดา) สร้างstd::functionออกมาส่งผ่านไปยังrun_in_ui_threadฟังก์ชั่นจากนั้นรอให้มันเสร็จสิ้นการทำงานในเธรดหลัก
ในกรณีที่ (A) ที่ถูกสร้างโดยตรงจากแลมบ์ดาของเราซึ่งถูกนำมาใช้แล้วภายในstd::function run_in_ui_threadแลมบ์ดานั้นmoveเข้าสู่std::functionดังนั้นสถานะเคลื่อนย้ายใด ๆ จะถูกดำเนินการอย่างมีประสิทธิภาพ
ในกรณีที่สองชั่วคราวstd::functionถูกสร้างขึ้นแลมบ์ดาเป็นmoveวันที่เป็นมันแล้วว่าชั่วคราวจะถูกใช้โดยการอ้างอิงภายในstd::functionrun_in_ui_thread
จนถึงตอนนี้ดีมาก - พวกเขาสองคนทำงานได้เหมือนกัน ยกเว้นrun_in_ui_threadจะทำสำเนาของอาร์กิวเมนต์ฟังก์ชั่นเพื่อส่งไปยังเธรด UI เพื่อดำเนินการ! (มันจะกลับมาก่อนที่มันจะเสร็จสิ้นดังนั้นจึงไม่สามารถใช้การอ้างอิงกับมันได้) สำหรับกรณี (A) เราก็ลงในระยะยาวการจัดเก็บข้อมูล ในกรณี (B), เราถูกบังคับให้คัดลอกmovestd::functionstd::function
ร้านค้านั้นทำให้การส่งผ่านโดยมีมูลค่าเหมาะสมที่สุด หากมีความเป็นไปได้ใด ๆ ที่คุณกำลังเก็บสำเนาของstd::functionผ่านค่า มิฉะนั้นทั้งสองวิธีนั้นจะเทียบเท่ากันโดยประมาณ: ข้อเสียเพียงข้อเดียวคือถ้าคุณใช้วิธีการที่ใหญ่std::functionและมีวิธีย่อยหนึ่งหลังจากใช้วิธีอื่น แบริ่งนั้นจะเป็นที่มีประสิทธิภาพเป็นmoveconst&
ขณะนี้มีบางอย่างที่แตกต่างอื่น ๆ std::functionระหว่างคนทั้งสองที่ส่วนใหญ่จะเตะในถ้าเรามีรัฐถาวรภายใน
สมมติว่าstd::functionเก็บวัตถุบางอย่างด้วยoperator() constแต่ก็มีmutableสมาชิกข้อมูลบางส่วนที่มันปรับเปลี่ยน (วิธีหยาบคาย!)
ในstd::function<> const&กรณีmutableที่สมาชิกข้อมูลที่แก้ไขจะเผยแพร่จากการเรียกใช้ฟังก์ชัน ในstd::function<>กรณีที่พวกเขาจะไม่
นี่เป็นกรณีมุมที่ค่อนข้างแปลก
คุณต้องการที่จะปฏิบัติstd::functionเหมือนคนอื่น ๆ ที่อาจเป็นประเภทที่มีน้ำหนักมากและเคลื่อนย้ายได้อย่างถูก การย้ายมีราคาถูกการคัดลอกอาจมีราคาแพง
sizeof(std::function)จะไม่เกิน2 * sizeof(size_t)ซึ่งเป็นขนาดที่เล็กที่สุดที่คุณเคยพิจารณาสำหรับการอ้างอิง const