ตัวอย่างเช่น:
Beta_ab&&
Beta::toAB() const {
return move(Beta_ab(1, 1));
}
ตัวอย่างเช่น:
Beta_ab&&
Beta::toAB() const {
return move(Beta_ab(1, 1));
}
คำตอบ:
Beta_ab&&
Beta::toAB() const {
return move(Beta_ab(1, 1));
}
สิ่งนี้ส่งคืนการอ้างอิงแบบห้อยเช่นเดียวกับกรณีอ้างอิง lvalue หลังจากฟังก์ชั่นกลับมาวัตถุชั่วคราวจะถูกทำลาย คุณควรส่งคืนBeta_ab
ตามมูลค่าดังต่อไปนี้
Beta_ab
Beta::toAB() const {
return Beta_ab(1, 1);
}
ตอนนี้มันถูกย้ายBeta_ab
วัตถุชั่วคราวไปยังค่าส่งคืนของฟังก์ชัน หากคอมไพเลอร์สามารถทำได้คอมไพเลอร์จะหลีกเลี่ยงการย้ายทั้งหมดโดยใช้ RVO (การเพิ่มประสิทธิภาพค่าส่งคืน) ตอนนี้คุณสามารถทำสิ่งต่อไปนี้ได้
Beta_ab ab = others.toAB();
และจะย้ายโครงสร้างชั่วคราวเข้าไปab
หรือทำ RVO เพื่อละเว้นการย้ายหรือคัดลอกทั้งหมด ฉันแนะนำให้คุณอ่านBoostCon09 Rvalue References 101ซึ่งอธิบายถึงเรื่องนี้และ (N) RVO โต้ตอบกับสิ่งนี้อย่างไร
กรณีของคุณในการส่งคืนข้อมูลอ้างอิง rvalue เป็นความคิดที่ดีในโอกาสอื่น ๆ ลองนึกภาพคุณมีgetAB()
ฟังก์ชันที่คุณมักเรียกใช้ชั่วคราว ไม่เหมาะสมที่จะทำให้มันส่งคืนการอ้างอิง const lvalue สำหรับ rvalue temporaries คุณสามารถใช้งานได้เช่นนี้
struct Beta {
Beta_ab ab;
Beta_ab const& getAB() const& { return ab; }
Beta_ab && getAB() && { return move(ab); }
};
โปรดทราบว่าmove
ในกรณีนี้ไม่ใช่ทางเลือกเนื่องจากab
ไม่ใช่ค่าอัตโนมัติแบบโลคัลหรือค่าชั่วคราว ตอนนี้ref-qualifier &&
บอกว่าฟังก์ชันที่สองถูกเรียกใช้ใน rvalue temporaries ทำการย้ายต่อไปนี้แทนการคัดลอก
Beta_ab ab = Beta().getAB();
มันสามารถมีประสิทธิภาพมากขึ้นตัวอย่างเช่นในบริบทที่แตกต่างบิต:
template <typename T>
T&& min_(T&& a, T &&b) {
return std::move(a < b? a: b);
}
int main() {
const std::string s = min_(std::string("A"), std::string("B"));
fprintf(stderr, "min: %s\n", s.c_str());
return 0;
}
ในฐานะที่เป็นข้อสังเกตที่น่าสนใจในเครื่องของฉันclang++ -O3
สร้าง 54 คำแนะนำสำหรับการโค้ดข้างต้นเมื่อเทียบกับ 62 std::min
คำแนะนำสำหรับการปกติ แต่ด้วยการ-O0
สร้าง 518 คำแนะนำสำหรับการโค้ดข้างต้นเมื่อเทียบกับ 481 std::min
ปกติ
for(:)
และรวมเข้ากับวัตถุที่ไม่ได้ปันส่วน แก้ไข: ideone.com/tQVOal
std::move()
ใช้เป็นเพียงการแสดงที่ชัดเจนเพื่อแสดงให้เห็นประเด็นที่ชัดเจนยิ่งขึ้น ไม่ใช่รหัสที่คุณจะคัดลอกวางลงในโครงการของคุณ ไม่ขัดแย้งกับคำตอบที่ได้รับการโหวตสูงสุดเนื่องจากมีวัตถุชั่วคราวถูกสร้างขึ้นภายในฟังก์ชัน วัตถุที่ส่งคืนในที่นี้เป็นหนึ่งในอาร์กิวเมนต์ (วัตถุชั่วคราวจะถูกทำลายเป็นขั้นตอนสุดท้ายในการประเมินนิพจน์เต็มที่ (ศัพท์) ประกอบด้วยจุดที่สร้างขึ้น)