1. "มันคืออะไร"
ในขณะที่std::move()
เป็นเทคนิคที่ฟังก์ชั่น - ผมจะบอกว่ามันไม่ได้จริงๆฟังก์ชั่น มันเป็นตัวแปลงระหว่างวิธีที่คอมไพเลอร์พิจารณาค่าของนิพจน์
2. "ทำอะไรได้บ้าง"
สิ่งแรกที่ควรทราบคือstd::move()
ไม่ได้ย้ายอะไรจริงๆ มันจะแปลงการแสดงออกจากการเป็นlvalue (เช่นตัวแปรชื่อ) จะเป็นXvalue xvalue บอกคอมไพเลอร์:
คุณสามารถปล้นฉันย้ายสิ่งที่ฉันถือและใช้ที่อื่น (เนื่องจากฉันกำลังจะถูกทำลายในไม่ช้า) "
กล่าวอีกนัยหนึ่งเมื่อคุณใช้std::move(x)
คุณอนุญาตให้คอมไพเลอร์แปลค่าx
ได้ ดังนั้นถ้าx
มีพูดบัฟเฟอร์ของตัวเองในหน่วยความจำ - หลังจากstd::move()
ไอเอ็นจีคอมไพเลอร์สามารถมีวัตถุอื่นเป็นเจ้าของมันแทน
นอกจากนี้คุณยังสามารถย้ายจากprvalue (เช่นชั่วคราวที่คุณผ่านไป) แต่ไม่ค่อยมีประโยชน์
3. "ควรใช้เมื่อใด"
อีกวิธีหนึ่งในการถามคำถามนี้คือ "ฉันจะใช้ทรัพยากรของวัตถุที่มีอยู่ได้อย่างไร" ดีถ้าคุณเขียนรหัสแอปพลิเคชันคุณอาจจะไม่ได้ยุ่งกับวัตถุชั่วคราวที่สร้างขึ้นโดยคอมไพเลอร์ ดังนั้นส่วนใหญ่คุณจะทำเช่นนี้ในสถานที่เช่นตัวสร้างวิธีการดำเนินการฟังก์ชั่นมาตรฐานห้องสมุด - อัลกอริทึมเหมือน ฯลฯ ที่วัตถุได้รับการสร้างและทำลายโดยอัตโนมัติมาก แน่นอนว่าเป็นเพียงกฎง่ายๆ
การใช้งานทั่วไปคือทรัพยากร 'ย้าย' จากวัตถุหนึ่งไปอีกวัตถุหนึ่งแทนที่จะคัดลอก @Gillailla เชื่อมโยงไปยังหน้านี้ซึ่งมีตัวอย่างสั้น ๆ ที่ตรงไปตรงมา: การแลกเปลี่ยนสองวัตถุที่มีการคัดลอกน้อย
template <class T>
swap(T& a, T& b) {
T tmp(a); // we now have two copies of a
a = b; // we now have two copies of b (+ discarded a copy of a)
b = tmp; // we now have two copies of tmp (+ discarded a copy of b)
}
การใช้การย้ายช่วยให้คุณสลับทรัพยากรแทนที่จะคัดลอกไปมา:
template <class T>
swap(T& a, T& b) {
T tmp(std::move(a));
a = std::move(b);
b = std::move(tmp);
}
คิดถึงสิ่งที่เกิดขึ้นเมื่อT
พูดvector<int>
ขนาด n ในเวอร์ชันแรกที่คุณอ่านและเขียนอิลิเมนต์ 3 * n ในเวอร์ชันที่สองคุณจะอ่านและเขียนเพียง 3 พอยน์เตอร์ไปยังบัฟเฟอร์เวกเตอร์รวมถึงขนาดบัฟเฟอร์ 3 ตัว แน่นอนว่าผู้เรียนT
ต้องรู้วิธีการเคลื่อนไหว คลาสของคุณควรมีโอเปอเรเตอร์การกำหนดและตัวสร้างการย้ายสำหรับคลาสT
เพื่อให้สิ่งนี้ใช้ได้