Trong trường hợp của bạn, returnedStr
sẽ được di chuyển-xây dựng từ giá trị trả về của GetString()
, nhưng mà giá trị trả về sẽ được sao chép-xây dựng từ str
(1). Nếu str
không phải là const
, giá trị trả về sẽ được di chuyển từ nó. Lưu ý rằng trong cả hai trường hợp, tối ưu hóa giá trị trả về vẫn có thể áp dụng, do đó trình biên dịch vẫn có thể xây dựng giá trị trả về (hoặc thậm chí là str
) trực tiếp trong không gian returnedStr
, bỏ qua một hoặc cả hai công trình sao chép/di chuyển. Này được cấp bằng C++ 11 12,8/31:
Khi tiêu chí nhất định được đáp ứng, một thực hiện được phép bỏ qua việc xây dựng sao chép/di chuyển của một đối tượng lớp , ngay cả khi sao chép/di chuyển constructor và/hoặc destructor cho đối tượng có tác dụng phụ. Trong các trường hợp như vậy, việc triển khai xử lý nguồn và đích của thao tác sao chép/di chuyển bị bỏ qua chỉ đơn giản là hai cách khác nhau là cách đề cập đến cùng một đối tượng và sự phá hủy đối tượng đó xảy ra sau này là khi hai đối tượng sẽ bị phá hủy mà không có sự tối ưu hóa. sự bỏ bớt này sao chép/di chuyển hoạt động, được gọi là bản sao sự bỏ bớt, được phép trong các trường hợp sau (có thể được kết hợp để loại bỏ nhiều bản sao):
trong một tuyên bố return
trong một hàm với một lớp kiểu trả về, khi biểu thức là tên của đối tượng tự động không bay hơi (khác với hàm hoặc tham số mệnh đề bắt buộc) với cùng loại cv-unqualified làm kiểu trả về hàm, thao tác sao chép/di chuyển có thể bỏ qua bằng cách xây dựng đối tượng tự động trực tiếp vào giá trị trả về của hàm
...
khi một đối tượng lớp tạm thời chưa được ràng buộc với một tài liệu tham khảo (12.2) sẽ được sao chép/di chuyển đến một đối tượng lớp với kiểu cv-không đủ tiêu chuẩn đó, sao chép/hoạt động di chuyển có thể được bỏ qua bởi xây dựng các đối tượng tạm thời trực tiếp vào mục tiêu của bản sao bỏ qua/di chuyển
điểm đạn đầu tiên bao gồm các sự bỏ bớt việc xây dựng giá trị trả về, người kia bao gồm di chuyển trở lại giá trị thành returnedStr
. Lưu ý yêu cầu về loại "cùng loại cv không đủ điều kiện", điều này có nghĩa là loại này hoạt động bất kể các vòng loại cv.
(1) Lưu ý rằng nếu chúng ta đã nói về một lớp X
khác hơn std::string
, một trong đó cung cấp một constructor chuyển tham gia một const X&&
, sau đó thực sự là giá trị trả về sẽ là động thái được xây dựng sử dụng constructor này (bất cứ điều gì ngữ nghĩa nó có thể có).
@PiotrS. Thêm vào, mặc dù tôi không nghĩ câu trả lời thực sự cần. Nó chỉ là bản sao bình thường trong công việc. – Angew
tốt đẹp, nhưng tôi không có nghĩa là yêu cầu cho ellision, thay vì trả về thường xuyên –
, 'X (const X &&);' là một * constructor di chuyển * hợp lệ sẽ được gọi cho ví dụ trên nếu được khai báo, ngay cả khi nó không phải là hợp lý –