Tôi hiểu rằng trong C ++ 11, khi bạn trả về một biến cục bộ từ một hàm theo giá trị, trình biên dịch được phép coi biến đó là một tham chiếu giá trị r và 'di chuyển' nó ra khỏi hàm để trả về nó (nếu RVO / NRVO không xảy ra thay vào đó, tất nhiên).
Câu hỏi của tôi là, điều này không thể phá vỡ mã hiện có?
Hãy xem xét các mã sau đây:
#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;
}
Tôi nghĩ rằng một kẻ hủy diệt của một đối tượng cục bộ có thể tham chiếu đến đối tượng được di chuyển ngầm, và do đó bất ngờ nhìn thấy một đối tượng 'trống rỗng'. Tôi cố gắng để kiểm tra điều này (xem http://ideone.com/ZURoeT ), nhưng tôi đã có kết quả chính xác 'mà không có sự rõ ràng std::move
trong foobar()
. Tôi đoán đó là do NRVO, nhưng tôi đã không cố gắng sắp xếp lại mã để vô hiệu hóa điều đó.
Tôi có đúng không khi chuyển đổi này (gây ra sự dịch chuyển khỏi chức năng) xảy ra ngầm và có thể phá vỡ mã hiện có?
CẬP NHẬT Dưới đây là một ví dụ minh họa những gì tôi đang nói. Hai liên kết sau đây cho cùng một mã. http://ideone.com/4GFIRu - C ++ 03 http://ideone.com/FcL2Xj - C ++ 11
Nếu bạn nhìn vào đầu ra, nó khác.
Vì vậy, tôi đoán rằng câu hỏi này bây giờ đã trở thành, điều này có được xem xét khi thêm di chuyển ngầm vào tiêu chuẩn hay không, và đã quyết định rằng có thể thêm thay đổi vi phạm này không vì loại mã này có đủ hiếm không? Tôi cũng tự hỏi liệu có trình biên dịch nào sẽ cảnh báo trong những trường hợp như thế này không ...