2013-07-30 27 views
14

Trên trang How to: Write a Move Constructor Microsoft có một ví dụ về cách viết một hàm tạo di chuyển. Về cơ bản nó có dạng:std :: di chuyển trên một biến mà đã là T &&

MyClass::MyClass(MyClass&& lhs) 
{ 
    *this = std::move(lhs); 
} 

Tôi đã thử và std::move thực sự là bắt buộc ở đây, nhưng tại sao? Tôi nghĩ điều duy nhất di chuyển là chuyển đổi thành T&&. Nhưng lhs đã thuộc loại MyClass&&, phải không?

+14

tài liệu tham khảo được đặt tên là lvalues. *Luôn luôn*. –

+3

Nó dài, nhưng [đây là một đọc tốt] (http://thbecker.net/articles/rvalue_references/section_01.html) để tìm hiểu tất cả về tài liệu tham khảo rvalue. –

+0

R. Martino Fernandes: Cảm ơn! Tôi chấp nhận điều đó như một câu trả lời. – Petter

Trả lời

20

Tham chiếu rvalue được đặt tên là giá trị. Tham chiếu rvalue chưa đặt tên là các giá trị. này rất quan trọng để hiểu tại sao cuộc gọi std :: Động thái này là cần thiết trong: foo&& r = foo(); foo f = std::move(r);

Hãy xem câu trả lời này: https://stackoverflow.com/a/5481588/1394283 Nó giải thích nó rất tốt.


Hãy nhìn vào chức năng này:

void foo(X&& x) 
{ 
    X anotherX = x; 
    // ... 
} 

Câu hỏi thú vị là: có tình trạng quá tải của X 's copy constructor được gọi trong cơ thể của foo? Ở đây, x là một biến được khai báo là tham chiếu rvalue. Do đó, nó là khá hợp lý để mong đợi rằng x chính nó cũng nên ràng buộc như một rvalue, đó là, X(X&& rhs); nên được gọi.

phép sematics di chuyển được áp dụng ngầm để một cái gì đó mà có một cái tên, như trong

X anotherX = x; 
// x is still in scope! 

sẽ gây nhầm lẫn và dễ bị lỗi nguy hiểm bởi vì điều mà từ đó chúng ta chỉ cần di chuyển, có nghĩa là, những điều mà chúng tôi vừa ăn cắp, vẫn có thể truy cập trên các dòng mã tiếp theo. Nhưng toàn bộ quan điểm của ngữ nghĩa di chuyển là áp dụng nó chỉ khi nó "không quan trọng", theo nghĩa là thứ mà từ đó chúng ta di chuyển chết và biến mất ngay sau khi di chuyển.

Đó là lý do tại sao các nhà thiết kế tài liệu tham khảo rvalue đã chọn một giải pháp đó là tinh tế hơn một chút so với:

Những điều đó được khai báo là tài liệu tham khảo rvalue có thể lvalues ​​hoặc rvalues. Tiêu chí phân biệt là: nếu có tên, thì đó là một giá trị. Nếu không, nó là một giá trị.

Nguồn: http://thbecker.net/articles/rvalue_references/section_05.html

+1

Để công bằng, giá trị trả về của 'T & foo()' không có tên nhưng là một giá trị. – Yakk

+0

@Yakk Bạn nói đúng. _Các tham chiếu ** Giá trị không được đặt tên ** là các giá trị. Ở đây chúng ta chỉ nói về các giá trị. –

Các vấn đề liên quan