ความเข้าใจของฉันคือว่าใน C ++ 11 เมื่อคุณส่งคืนตัวแปรโลคัลจากฟังก์ชันตามค่าคอมไพเลอร์ได้รับอนุญาตให้จัดการกับตัวแปรนั้นเป็นการอ้างอิงค่า r-value และ 'ย้าย' ออกจากฟังก์ชันเพื่อส่งคืน (ถ้า RVO / NRVO ไม่ได้เกิดขึ้นแทนแน่นอน)
คำถามของฉันคือจะไม่ทำลายรหัสที่มีอยู่นี้หรือไม่
พิจารณารหัสต่อไปนี้:
#include <iostream>
#include <string>
struct bar
{
bar(const std::string& str) : _str(str) {}
bar(const bar&) = delete;
bar(bar&& other) : _str(std::move(other._str)) {other._str = "Stolen";}
void print() {std::cout << _str << std::endl;}
std::string _str;
};
struct foo
{
foo(bar& b) : _b(b) {}
~foo() {_b.print();}
bar& _b;
};
bar foobar()
{
bar b("Hello, World!");
foo f(b);
return std::move(b);
}
int main()
{
foobar();
return EXIT_SUCCESS;
}
ความคิดของฉันคือว่ามันจะเป็นไปได้สำหรับ destructor ของวัตถุในท้องถิ่นเพื่ออ้างอิงวัตถุที่ถูกย้ายโดยปริยายและดังนั้นจึงเห็นวัตถุ 'ว่างเปล่า' โดยไม่คาดคิด ผมพยายามที่จะทดสอบนี้ (ดูhttp://ideone.com/ZURoeT ) แต่ผมได้ 'ถูกต้อง' ผลโดยไม่ต้องชัดเจนในstd::move
foobar()
ฉันคาดเดาว่าเป็นเพราะ NRVO แต่ฉันไม่ได้พยายามจัดเรียงรหัสใหม่เพื่อปิดการใช้งาน
ฉันถูกต้องหรือไม่ว่าการเปลี่ยนแปลงนี้ (ทำให้เกิดการย้ายออกจากฟังก์ชัน) เกิดขึ้นโดยปริยายและอาจทำให้รหัสที่มีอยู่เสียหายได้?
อัพเดทที่ นี่เป็นตัวอย่างที่แสดงสิ่งที่ฉันกำลังพูดถึง ลิงค์สองลิงค์ต่อไปนี้ใช้สำหรับรหัสเดียวกัน http://ideone.com/4GFIRu - C ++ 03 http://ideone.com/FcL2Xj - C ++ 11
ถ้าคุณดูผลลัพธ์มันต่างกัน
ดังนั้นฉันเดาว่าตอนนี้กลายเป็นคำถามนี้ได้รับการพิจารณาเมื่อเพิ่มการย้ายโดยนัยไปยังมาตรฐานและได้มีการตัดสินใจแล้วว่ามันก็โอเคที่จะเพิ่มการเปลี่ยนแปลงที่ทำลายนี้เนื่องจากโค้ดชนิดนี้หายากพอหรือไม่ ฉันยังสงสัยว่าคอมไพเลอร์ใด ๆ จะเตือนในกรณีเช่นนี้ ...